blob: 671f5ed1eec033ff3dbba15b83bd281e44de63ce [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"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070036#include "libANGLE/Workarounds.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040037#include "libANGLE/formatutils.h"
Martin Radev66fb8202016-07-28 11:45:20 +030038#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040039#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040040#include "libANGLE/renderer/ContextImpl.h"
41#include "libANGLE/renderer/EGLImplFactory.h"
42#include "libANGLE/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050048std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030049 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
Geoff Lang4ddf5af2016-12-01 14:30:44 -050068std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030069 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Geoff Langfeb8c682017-02-13 16:07:35 -0500201bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
202{
203 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
204}
205
Jamie Madille08a1d32017-03-07 17:24:06 -0500206bool GetRobustResourceInit(const egl::AttributeMap &attribs)
207{
208 return (attribs.get(EGL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
209}
210
Martin Radev9d901792016-07-15 15:58:58 +0300211std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
212{
213 std::string labelName;
214 if (label != nullptr)
215 {
216 size_t labelLength = length < 0 ? strlen(label) : length;
217 labelName = std::string(label, labelLength);
218 }
219 return labelName;
220}
221
222void GetObjectLabelBase(const std::string &objectLabel,
223 GLsizei bufSize,
224 GLsizei *length,
225 GLchar *label)
226{
227 size_t writeLength = objectLabel.length();
228 if (label != nullptr && bufSize > 0)
229 {
230 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
231 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
232 label[writeLength] = '\0';
233 }
234
235 if (length != nullptr)
236 {
237 *length = static_cast<GLsizei>(writeLength);
238 }
239}
240
Geoff Langf6db0982015-08-25 13:04:00 -0400241} // anonymous namespace
242
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000243namespace gl
244{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000245
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400246Context::Context(rx::EGLImplFactory *implFactory,
247 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400248 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500249 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500250 const egl::AttributeMap &attribs,
251 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300252
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500253 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500254 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500255 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700256 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500257 mCaps,
258 mTextureCaps,
259 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500260 mLimitations,
261 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700262 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500263 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400264 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500265 mClientType(EGL_OPENGL_ES_API),
266 mHasBeenCurrent(false),
267 mContextLost(false),
268 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700269 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500270 mResetStrategy(GetResetStrategy(attribs)),
271 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500272 mCurrentSurface(nullptr),
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500273 mSurfacelessFramebuffer(nullptr),
Jamie Madille14951e2017-03-09 18:55:16 -0500274 mWebGLContext(GetWebGLContext(attribs)),
275 mScratchBuffer(1000u)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276{
Geoff Lang077f20a2016-11-01 10:08:02 -0400277 if (mRobustAccess)
278 {
279 UNIMPLEMENTED();
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281
Jamie Madill4e0e6f82017-02-17 11:06:03 -0500282 initCaps(displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700283 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400284
Geoff Langeb66a6e2016-10-31 13:06:12 -0400285 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Jamie Madille08a1d32017-03-07 17:24:06 -0500286 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs),
287 GetRobustResourceInit(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400290
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291 // [OpenGL ES 2.0.24] section 3.7 page 83:
292 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
293 // and cube map texture state vectors respectively associated with them.
294 // In order that access to these initial textures not be lost, they are treated as texture
295 // objects all of whose names are 0.
296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500301 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400302
Geoff Langeb66a6e2016-10-31 13:06:12 -0400303 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 {
305 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400309 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500310 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400311 }
Geoff Lang3b573612016-10-31 14:08:10 -0400312 if (getClientVersion() >= Version(3, 1))
313 {
314 Texture *zeroTexture2DMultisample =
315 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
316 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800317
318 bindGenericAtomicCounterBuffer(0);
319 for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++)
320 {
321 bindIndexedAtomicCounterBuffer(0, i, 0, 0);
322 }
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800323
324 bindGenericShaderStorageBuffer(0);
325 for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++)
326 {
327 bindIndexedShaderStorageBuffer(0, i, 0, 0);
328 }
Geoff Lang3b573612016-10-31 14:08:10 -0400329 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
Ian Ewellbda75592016-04-18 17:25:54 -0400331 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
332 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400333 Texture *zeroTextureExternal =
334 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400335 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
336 }
337
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700338 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500339
Jamie Madill57a89722013-07-02 11:57:03 -0400340 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000341 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800342 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000343 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400344
Jamie Madill01a80ee2016-11-07 12:06:18 -0500345 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000346
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000347 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500348 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000349 {
350 bindIndexedUniformBuffer(0, i, 0, -1);
351 }
352
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000353 bindCopyReadBuffer(0);
354 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000355 bindPixelPackBuffer(0);
356 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000357
Geoff Langeb66a6e2016-10-31 13:06:12 -0400358 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400359 {
360 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
361 // In the initial state, a default transform feedback object is bound and treated as
362 // a transform feedback object with a name of zero. That object is bound any time
363 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400364 bindTransformFeedback(0);
365 }
Geoff Langc8058452014-02-03 12:04:11 -0500366
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700367 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500368
369 // Initialize dirty bit masks
370 // TODO(jmadill): additional ES3 state
371 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
372 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
373 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
374 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
375 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
376 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400377 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500378 // No dirty objects.
379
380 // Readpixels uses the pack state and read FBO
381 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
382 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
383 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
384 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
385 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400386 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500387 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
388
389 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
390 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
391 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
392 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
393 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
394 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
395 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
396 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
397 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
398 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
399 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
400 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
401
402 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
403 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700404 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500405 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
406 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400407
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400408 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409}
410
Jamie Madill70ee0f62017-02-06 16:04:20 -0500411void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500413 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400417 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418 }
419
Corentin Wallez80b24112015-08-25 16:41:57 -0400420 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400422 if (query.second != nullptr)
423 {
424 query.second->release();
425 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426 }
427
Corentin Wallez80b24112015-08-25 16:41:57 -0400428 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400429 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400430 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400431 }
432
Corentin Wallez80b24112015-08-25 16:41:57 -0400433 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500434 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500435 if (transformFeedback.second != nullptr)
436 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500437 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500438 }
Geoff Langc8058452014-02-03 12:04:11 -0500439 }
440
Jamie Madilldedd7b92014-11-05 16:30:36 -0500441 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400442 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800443 zeroTexture.second.set(nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400444 }
445 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446
Corentin Wallezccab69d2017-01-27 16:57:15 -0500447 SafeDelete(mSurfacelessFramebuffer);
448
Jamie Madill70ee0f62017-02-06 16:04:20 -0500449 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400450
Geoff Lang492a7e42014-11-05 13:27:06 -0500451 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452
453 mState.mBuffers->release(this);
454 mState.mShaderPrograms->release(this);
455 mState.mTextures->release(this);
456 mState.mRenderbuffers->release(this);
457 mState.mSamplers->release(this);
458 mState.mFenceSyncs->release(this);
459 mState.mPaths->release(this);
460 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461}
462
Jamie Madill70ee0f62017-02-06 16:04:20 -0500463Context::~Context()
464{
465}
466
467void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469 if (!mHasBeenCurrent)
470 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500472 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400473 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000474
Corentin Wallezc295e512017-01-27 17:47:50 -0500475 int width = 0;
476 int height = 0;
477 if (surface != nullptr)
478 {
479 width = surface->getWidth();
480 height = surface->getHeight();
481 }
482
483 mGLState.setViewportParams(0, 0, width, height);
484 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000485
486 mHasBeenCurrent = true;
487 }
488
Jamie Madill1b94d432015-08-07 13:23:23 -0400489 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700490 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400491
Jamie Madill70ee0f62017-02-06 16:04:20 -0500492 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500493
494 Framebuffer *newDefault = nullptr;
495 if (surface != nullptr)
496 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500497 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500498 mCurrentSurface = surface;
499 newDefault = surface->getDefaultFramebuffer();
500 }
501 else
502 {
503 if (mSurfacelessFramebuffer == nullptr)
504 {
505 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
506 }
507
508 newDefault = mSurfacelessFramebuffer;
509 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000510
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 // Update default framebuffer, the binding of the previous default
512 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400513 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700514 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400515 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700516 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400517 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700518 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400519 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700520 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400521 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500522 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400523 }
Ian Ewell292f0052016-02-04 10:37:32 -0500524
525 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700526 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
Jamie Madill70ee0f62017-02-06 16:04:20 -0500529void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400530{
Corentin Wallez37c39792015-08-20 14:19:46 -0400531 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500532 Framebuffer *currentDefault = nullptr;
533 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400534 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500535 currentDefault = mCurrentSurface->getDefaultFramebuffer();
536 }
537 else if (mSurfacelessFramebuffer != nullptr)
538 {
539 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400540 }
541
Corentin Wallezc295e512017-01-27 17:47:50 -0500542 if (mGLState.getReadFramebuffer() == currentDefault)
543 {
544 mGLState.setReadFramebufferBinding(nullptr);
545 }
546 if (mGLState.getDrawFramebuffer() == currentDefault)
547 {
548 mGLState.setDrawFramebufferBinding(nullptr);
549 }
550 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
551
552 if (mCurrentSurface)
553 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500554 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500555 mCurrentSurface = nullptr;
556 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400557}
558
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000559GLuint Context::createBuffer()
560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000562}
563
564GLuint Context::createProgram()
565{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500566 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567}
568
569GLuint Context::createShader(GLenum type)
570{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500571 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000572}
573
574GLuint Context::createTexture()
575{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500576 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577}
578
579GLuint Context::createRenderbuffer()
580{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500581 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582}
583
Geoff Lang882033e2014-09-30 11:26:07 -0400584GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400585{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500586 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400587
Cooper Partind8e62a32015-01-29 15:21:25 -0800588 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400589}
590
Sami Väisänene45e53b2016-05-25 10:36:04 +0300591GLuint Context::createPaths(GLsizei range)
592{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500593 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300594 if (resultOrError.isError())
595 {
596 handleError(resultOrError.getError());
597 return 0;
598 }
599 return resultOrError.getResult();
600}
601
Jamie Madill57a89722013-07-02 11:57:03 -0400602GLuint Context::createVertexArray()
603{
Geoff Lang36167ab2015-12-07 10:27:14 -0500604 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
605 mVertexArrayMap[vertexArray] = nullptr;
606 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400607}
608
Jamie Madilldc356042013-07-19 16:36:57 -0400609GLuint Context::createSampler()
610{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500611 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400612}
613
Geoff Langc8058452014-02-03 12:04:11 -0500614GLuint Context::createTransformFeedback()
615{
Geoff Lang36167ab2015-12-07 10:27:14 -0500616 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
617 mTransformFeedbackMap[transformFeedback] = nullptr;
618 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500619}
620
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621// Returns an unused framebuffer name
622GLuint Context::createFramebuffer()
623{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500624 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625}
626
Jamie Madill33dc8432013-07-26 11:55:05 -0400627GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000628{
Jamie Madill33dc8432013-07-26 11:55:05 -0400629 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400631 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632
633 return handle;
634}
635
636// Returns an unused query name
637GLuint Context::createQuery()
638{
639 GLuint handle = mQueryHandleAllocator.allocate();
640
Yunchao Hed7297bf2017-04-19 15:27:10 +0800641 mQueryMap[handle] = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642
643 return handle;
644}
645
646void Context::deleteBuffer(GLuint buffer)
647{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500648 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649 {
650 detachBuffer(buffer);
651 }
Jamie Madill893ab082014-05-16 16:56:10 -0400652
Jamie Madill6c1f6712017-02-14 19:08:04 -0500653 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654}
655
656void Context::deleteShader(GLuint shader)
657{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500658 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659}
660
661void Context::deleteProgram(GLuint program)
662{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500663 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664}
665
666void Context::deleteTexture(GLuint texture)
667{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500668 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669 {
670 detachTexture(texture);
671 }
672
Jamie Madill6c1f6712017-02-14 19:08:04 -0500673 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674}
675
676void Context::deleteRenderbuffer(GLuint renderbuffer)
677{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500678 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000679 {
680 detachRenderbuffer(renderbuffer);
681 }
Jamie Madill893ab082014-05-16 16:56:10 -0400682
Jamie Madill6c1f6712017-02-14 19:08:04 -0500683 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000684}
685
Jamie Madillcd055f82013-07-26 11:55:15 -0400686void Context::deleteFenceSync(GLsync fenceSync)
687{
688 // The spec specifies the underlying Fence object is not deleted until all current
689 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
690 // and since our API is currently designed for being called from a single thread, we can delete
691 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500692 mState.mFenceSyncs->deleteObject(this,
693 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400694}
695
Sami Väisänene45e53b2016-05-25 10:36:04 +0300696void Context::deletePaths(GLuint first, GLsizei range)
697{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500698 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300699}
700
701bool Context::hasPathData(GLuint path) const
702{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500703 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300704 if (pathObj == nullptr)
705 return false;
706
707 return pathObj->hasPathData();
708}
709
710bool Context::hasPath(GLuint path) const
711{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500712 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300713}
714
715void Context::setPathCommands(GLuint path,
716 GLsizei numCommands,
717 const GLubyte *commands,
718 GLsizei numCoords,
719 GLenum coordType,
720 const void *coords)
721{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500722 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300723
724 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
725}
726
727void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
728{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500729 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300730
731 switch (pname)
732 {
733 case GL_PATH_STROKE_WIDTH_CHROMIUM:
734 pathObj->setStrokeWidth(value);
735 break;
736 case GL_PATH_END_CAPS_CHROMIUM:
737 pathObj->setEndCaps(static_cast<GLenum>(value));
738 break;
739 case GL_PATH_JOIN_STYLE_CHROMIUM:
740 pathObj->setJoinStyle(static_cast<GLenum>(value));
741 break;
742 case GL_PATH_MITER_LIMIT_CHROMIUM:
743 pathObj->setMiterLimit(value);
744 break;
745 case GL_PATH_STROKE_BOUND_CHROMIUM:
746 pathObj->setStrokeBound(value);
747 break;
748 default:
749 UNREACHABLE();
750 break;
751 }
752}
753
754void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
755{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500756 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300757
758 switch (pname)
759 {
760 case GL_PATH_STROKE_WIDTH_CHROMIUM:
761 *value = pathObj->getStrokeWidth();
762 break;
763 case GL_PATH_END_CAPS_CHROMIUM:
764 *value = static_cast<GLfloat>(pathObj->getEndCaps());
765 break;
766 case GL_PATH_JOIN_STYLE_CHROMIUM:
767 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
768 break;
769 case GL_PATH_MITER_LIMIT_CHROMIUM:
770 *value = pathObj->getMiterLimit();
771 break;
772 case GL_PATH_STROKE_BOUND_CHROMIUM:
773 *value = pathObj->getStrokeBound();
774 break;
775 default:
776 UNREACHABLE();
777 break;
778 }
779}
780
781void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
782{
783 mGLState.setPathStencilFunc(func, ref, mask);
784}
785
Jamie Madill57a89722013-07-02 11:57:03 -0400786void Context::deleteVertexArray(GLuint vertexArray)
787{
Geoff Lang36167ab2015-12-07 10:27:14 -0500788 auto iter = mVertexArrayMap.find(vertexArray);
789 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000790 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500791 VertexArray *vertexArrayObject = iter->second;
792 if (vertexArrayObject != nullptr)
793 {
794 detachVertexArray(vertexArray);
795 delete vertexArrayObject;
796 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000797
Geoff Lang36167ab2015-12-07 10:27:14 -0500798 mVertexArrayMap.erase(iter);
799 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400800 }
801}
802
Jamie Madilldc356042013-07-19 16:36:57 -0400803void Context::deleteSampler(GLuint sampler)
804{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500805 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400806 {
807 detachSampler(sampler);
808 }
809
Jamie Madill6c1f6712017-02-14 19:08:04 -0500810 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400811}
812
Geoff Langc8058452014-02-03 12:04:11 -0500813void Context::deleteTransformFeedback(GLuint transformFeedback)
814{
Geoff Lang6e60d6b2017-04-12 12:59:04 -0400815 if (transformFeedback == 0)
816 {
817 return;
818 }
819
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500820 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500821 if (iter != mTransformFeedbackMap.end())
822 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500823 TransformFeedback *transformFeedbackObject = iter->second;
824 if (transformFeedbackObject != nullptr)
825 {
826 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500827 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500828 }
829
Geoff Lang50b3fe82015-12-08 14:49:12 +0000830 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500831 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500832 }
833}
834
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835void Context::deleteFramebuffer(GLuint framebuffer)
836{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500837 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838 {
839 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500841
Jamie Madill6c1f6712017-02-14 19:08:04 -0500842 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843}
844
Jamie Madill33dc8432013-07-26 11:55:05 -0400845void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000846{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500847 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848
Jamie Madill33dc8432013-07-26 11:55:05 -0400849 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400851 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400853 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854 }
855}
856
857void Context::deleteQuery(GLuint query)
858{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500859 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860 if (queryObject != mQueryMap.end())
861 {
862 mQueryHandleAllocator.release(queryObject->first);
863 if (queryObject->second)
864 {
865 queryObject->second->release();
866 }
867 mQueryMap.erase(queryObject);
868 }
869}
870
Geoff Lang70d0f492015-12-10 17:45:46 -0500871Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500873 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000874}
875
Jamie Madill570f7c82014-07-03 10:38:54 -0400876Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000877{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500878 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000879}
880
Geoff Lang70d0f492015-12-10 17:45:46 -0500881Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000882{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500883 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884}
885
Jamie Madillcd055f82013-07-26 11:55:15 -0400886FenceSync *Context::getFenceSync(GLsync handle) const
887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500888 return mState.mFenceSyncs->getFenceSync(
889 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400890}
891
Jamie Madill57a89722013-07-02 11:57:03 -0400892VertexArray *Context::getVertexArray(GLuint handle) const
893{
894 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500895 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400896}
897
Jamie Madilldc356042013-07-19 16:36:57 -0400898Sampler *Context::getSampler(GLuint handle) const
899{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500900 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400901}
902
Geoff Langc8058452014-02-03 12:04:11 -0500903TransformFeedback *Context::getTransformFeedback(GLuint handle) const
904{
Geoff Lang36167ab2015-12-07 10:27:14 -0500905 auto iter = mTransformFeedbackMap.find(handle);
906 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500907}
908
Geoff Lang70d0f492015-12-10 17:45:46 -0500909LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
910{
911 switch (identifier)
912 {
913 case GL_BUFFER:
914 return getBuffer(name);
915 case GL_SHADER:
916 return getShader(name);
917 case GL_PROGRAM:
918 return getProgram(name);
919 case GL_VERTEX_ARRAY:
920 return getVertexArray(name);
921 case GL_QUERY:
922 return getQuery(name);
923 case GL_TRANSFORM_FEEDBACK:
924 return getTransformFeedback(name);
925 case GL_SAMPLER:
926 return getSampler(name);
927 case GL_TEXTURE:
928 return getTexture(name);
929 case GL_RENDERBUFFER:
930 return getRenderbuffer(name);
931 case GL_FRAMEBUFFER:
932 return getFramebuffer(name);
933 default:
934 UNREACHABLE();
935 return nullptr;
936 }
937}
938
939LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
940{
941 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
942}
943
Martin Radev9d901792016-07-15 15:58:58 +0300944void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
945{
946 LabeledObject *object = getLabeledObject(identifier, name);
947 ASSERT(object != nullptr);
948
949 std::string labelName = GetObjectLabelFromPointer(length, label);
950 object->setLabel(labelName);
951}
952
953void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
954{
955 LabeledObject *object = getLabeledObjectFromPtr(ptr);
956 ASSERT(object != nullptr);
957
958 std::string labelName = GetObjectLabelFromPointer(length, label);
959 object->setLabel(labelName);
960}
961
962void Context::getObjectLabel(GLenum identifier,
963 GLuint name,
964 GLsizei bufSize,
965 GLsizei *length,
966 GLchar *label) const
967{
968 LabeledObject *object = getLabeledObject(identifier, name);
969 ASSERT(object != nullptr);
970
971 const std::string &objectLabel = object->getLabel();
972 GetObjectLabelBase(objectLabel, bufSize, length, label);
973}
974
975void Context::getObjectPtrLabel(const void *ptr,
976 GLsizei bufSize,
977 GLsizei *length,
978 GLchar *label) const
979{
980 LabeledObject *object = getLabeledObjectFromPtr(ptr);
981 ASSERT(object != nullptr);
982
983 const std::string &objectLabel = object->getLabel();
984 GetObjectLabelBase(objectLabel, bufSize, length, label);
985}
986
Jamie Madilldc356042013-07-19 16:36:57 -0400987bool Context::isSampler(GLuint samplerName) const
988{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500989 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400990}
991
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500992void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500994 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700995 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996}
997
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800998void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
999{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001000 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001001 mGLState.setDrawIndirectBufferBinding(buffer);
1002}
1003
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001004void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001005{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001006 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Shao80957d92017-02-20 21:25:59 +08001007 mGLState.setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008}
1009
Jamie Madilldedd7b92014-11-05 16:30:36 -05001010void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001012 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001013
Jamie Madilldedd7b92014-11-05 16:30:36 -05001014 if (handle == 0)
1015 {
1016 texture = mZeroTextures[target].get();
1017 }
1018 else
1019 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001020 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -05001021 }
1022
1023 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001024 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001025}
1026
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001027void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001028{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001029 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1030 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001031 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001032}
1033
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001034void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001036 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1037 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001038 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001039}
1040
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001041void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001042{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001044 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001045}
1046
Shao80957d92017-02-20 21:25:59 +08001047void Context::bindVertexBuffer(GLuint bindingIndex,
1048 GLuint bufferHandle,
1049 GLintptr offset,
1050 GLsizei stride)
1051{
1052 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1053 mGLState.bindVertexBuffer(bindingIndex, buffer, offset, stride);
1054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001057{
Geoff Lang76b10c92014-09-05 16:28:14 -04001058 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001059 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001060 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001061 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001062}
1063
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001064void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001065{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001066 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001067 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001068}
1069
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001070void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1071 GLuint index,
1072 GLintptr offset,
1073 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001074{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001075 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001076 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001077}
1078
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001079void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001080{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001081 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001083}
1084
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001085void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1086 GLuint index,
1087 GLintptr offset,
1088 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001089{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001090 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001091 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001092}
1093
Jiajia Qin6eafb042016-12-27 17:04:07 +08001094void Context::bindGenericAtomicCounterBuffer(GLuint bufferHandle)
1095{
1096 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1097 mGLState.setGenericAtomicCounterBufferBinding(buffer);
1098}
1099
1100void Context::bindIndexedAtomicCounterBuffer(GLuint bufferHandle,
1101 GLuint index,
1102 GLintptr offset,
1103 GLsizeiptr size)
1104{
1105 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1106 mGLState.setIndexedAtomicCounterBufferBinding(index, buffer, offset, size);
1107}
1108
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001109void Context::bindGenericShaderStorageBuffer(GLuint bufferHandle)
1110{
1111 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1112 mGLState.setGenericShaderStorageBufferBinding(buffer);
1113}
1114
1115void Context::bindIndexedShaderStorageBuffer(GLuint bufferHandle,
1116 GLuint index,
1117 GLintptr offset,
1118 GLsizeiptr size)
1119{
1120 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
1121 mGLState.setIndexedShaderStorageBufferBinding(index, buffer, offset, size);
1122}
1123
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001124void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001125{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001126 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001127 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001128}
1129
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001130void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001131{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001132 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001133 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001134}
1135
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001136void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001137{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001138 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001139 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001140}
1141
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001142void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001143{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001144 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001145 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001146}
1147
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001148void Context::useProgram(GLuint program)
1149{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001150 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001151}
1152
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001153void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001154{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001155 TransformFeedback *transformFeedback =
1156 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001157 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001158}
1159
Geoff Lang5aad9672014-09-08 11:10:42 -04001160Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001163 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164
Geoff Lang5aad9672014-09-08 11:10:42 -04001165 // begin query
1166 Error error = queryObject->begin();
1167 if (error.isError())
1168 {
1169 return error;
1170 }
1171
1172 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001173 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174
He Yunchaoacd18982017-01-04 10:46:42 +08001175 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176}
1177
Geoff Lang5aad9672014-09-08 11:10:42 -04001178Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001180 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001181 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001182
Geoff Lang5aad9672014-09-08 11:10:42 -04001183 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184
Geoff Lang5aad9672014-09-08 11:10:42 -04001185 // Always unbind the query, even if there was an error. This may delete the query object.
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001186 mGLState.setActiveQuery(target, nullptr);
Geoff Lang5aad9672014-09-08 11:10:42 -04001187
1188 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189}
1190
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001191Error Context::queryCounter(GLuint id, GLenum target)
1192{
1193 ASSERT(target == GL_TIMESTAMP_EXT);
1194
1195 Query *queryObject = getQuery(id, true, target);
1196 ASSERT(queryObject);
1197
1198 return queryObject->queryCounter();
1199}
1200
1201void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1202{
1203 switch (pname)
1204 {
1205 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001206 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001207 break;
1208 case GL_QUERY_COUNTER_BITS_EXT:
1209 switch (target)
1210 {
1211 case GL_TIME_ELAPSED_EXT:
1212 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1213 break;
1214 case GL_TIMESTAMP_EXT:
1215 params[0] = getExtensions().queryCounterBitsTimestamp;
1216 break;
1217 default:
1218 UNREACHABLE();
1219 params[0] = 0;
1220 break;
1221 }
1222 break;
1223 default:
1224 UNREACHABLE();
1225 return;
1226 }
1227}
1228
Geoff Lang2186c382016-10-14 10:54:54 -04001229void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001230{
Geoff Lang2186c382016-10-14 10:54:54 -04001231 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001232}
1233
Geoff Lang2186c382016-10-14 10:54:54 -04001234void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001235{
Geoff Lang2186c382016-10-14 10:54:54 -04001236 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001237}
1238
Geoff Lang2186c382016-10-14 10:54:54 -04001239void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001240{
Geoff Lang2186c382016-10-14 10:54:54 -04001241 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001242}
1243
Geoff Lang2186c382016-10-14 10:54:54 -04001244void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001245{
Geoff Lang2186c382016-10-14 10:54:54 -04001246 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001247}
1248
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001249Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001250{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001251 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252}
1253
Jamie Madill33dc8432013-07-26 11:55:05 -04001254FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001256 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001257
Jamie Madill33dc8432013-07-26 11:55:05 -04001258 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001260 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 }
1262 else
1263 {
1264 return fence->second;
1265 }
1266}
1267
1268Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1269{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001270 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271
1272 if (query == mQueryMap.end())
1273 {
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001274 return nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 }
1276 else
1277 {
1278 if (!query->second && create)
1279 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001280 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 query->second->addRef();
1282 }
1283 return query->second;
1284 }
1285}
1286
Geoff Lang70d0f492015-12-10 17:45:46 -05001287Query *Context::getQuery(GLuint handle) const
1288{
1289 auto iter = mQueryMap.find(handle);
1290 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1291}
1292
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001293Texture *Context::getTargetTexture(GLenum target) const
1294{
Ian Ewellbda75592016-04-18 17:25:54 -04001295 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001296 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001297}
1298
Geoff Lang76b10c92014-09-05 16:28:14 -04001299Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001301 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001302}
1303
Geoff Lang492a7e42014-11-05 13:27:06 -05001304Compiler *Context::getCompiler() const
1305{
1306 return mCompiler;
1307}
1308
Jamie Madillc1d770e2017-04-13 17:31:24 -04001309void Context::getBooleanvImpl(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310{
1311 switch (pname)
1312 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001313 case GL_SHADER_COMPILER:
1314 *params = GL_TRUE;
1315 break;
1316 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1317 *params = mRobustAccess ? GL_TRUE : GL_FALSE;
1318 break;
1319 default:
1320 mGLState.getBooleanv(pname, params);
1321 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323}
1324
Jamie Madillc1d770e2017-04-13 17:31:24 -04001325void Context::getFloatvImpl(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326{
Shannon Woods53a94a82014-06-24 15:20:36 -04001327 // Queries about context capabilities and maximums are answered by Context.
1328 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001329 switch (pname)
1330 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001331 case GL_ALIASED_LINE_WIDTH_RANGE:
1332 params[0] = mCaps.minAliasedLineWidth;
1333 params[1] = mCaps.maxAliasedLineWidth;
1334 break;
1335 case GL_ALIASED_POINT_SIZE_RANGE:
1336 params[0] = mCaps.minAliasedPointSize;
1337 params[1] = mCaps.maxAliasedPointSize;
1338 break;
1339 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1340 ASSERT(mExtensions.textureFilterAnisotropic);
1341 *params = mExtensions.maxTextureAnisotropy;
1342 break;
1343 case GL_MAX_TEXTURE_LOD_BIAS:
1344 *params = mCaps.maxLODBias;
1345 break;
1346
1347 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1348 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1349 {
1350 ASSERT(mExtensions.pathRendering);
1351 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1352 memcpy(params, m, 16 * sizeof(GLfloat));
1353 }
Geoff Lange6d4e122015-06-29 13:33:55 -04001354 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001355
Jamie Madill231c7f52017-04-26 13:45:37 -04001356 default:
1357 mGLState.getFloatv(pname, params);
1358 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001359 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001360}
1361
Jamie Madillc1d770e2017-04-13 17:31:24 -04001362void Context::getIntegervImpl(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001363{
Shannon Woods53a94a82014-06-24 15:20:36 -04001364 // Queries about context capabilities and maximums are answered by Context.
1365 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001366
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001367 switch (pname)
1368 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001369 case GL_MAX_VERTEX_ATTRIBS:
1370 *params = mCaps.maxVertexAttributes;
1371 break;
1372 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1373 *params = mCaps.maxVertexUniformVectors;
1374 break;
1375 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1376 *params = mCaps.maxVertexUniformComponents;
1377 break;
1378 case GL_MAX_VARYING_VECTORS:
1379 *params = mCaps.maxVaryingVectors;
1380 break;
1381 case GL_MAX_VARYING_COMPONENTS:
1382 *params = mCaps.maxVertexOutputComponents;
1383 break;
1384 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1385 *params = mCaps.maxCombinedTextureImageUnits;
1386 break;
1387 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1388 *params = mCaps.maxVertexTextureImageUnits;
1389 break;
1390 case GL_MAX_TEXTURE_IMAGE_UNITS:
1391 *params = mCaps.maxTextureImageUnits;
1392 break;
1393 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1394 *params = mCaps.maxFragmentUniformVectors;
1395 break;
1396 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1397 *params = mCaps.maxFragmentUniformComponents;
1398 break;
1399 case GL_MAX_RENDERBUFFER_SIZE:
1400 *params = mCaps.maxRenderbufferSize;
1401 break;
1402 case GL_MAX_COLOR_ATTACHMENTS_EXT:
1403 *params = mCaps.maxColorAttachments;
1404 break;
1405 case GL_MAX_DRAW_BUFFERS_EXT:
1406 *params = mCaps.maxDrawBuffers;
1407 break;
1408 // case GL_FRAMEBUFFER_BINDING: // now equivalent to
1409 // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1410 case GL_SUBPIXEL_BITS:
1411 *params = 4;
1412 break;
1413 case GL_MAX_TEXTURE_SIZE:
1414 *params = mCaps.max2DTextureSize;
1415 break;
1416 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1417 *params = mCaps.maxCubeMapTextureSize;
1418 break;
1419 case GL_MAX_3D_TEXTURE_SIZE:
1420 *params = mCaps.max3DTextureSize;
1421 break;
1422 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1423 *params = mCaps.maxArrayTextureLayers;
1424 break;
1425 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1426 *params = mCaps.uniformBufferOffsetAlignment;
1427 break;
1428 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1429 *params = mCaps.maxUniformBufferBindings;
1430 break;
1431 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1432 *params = mCaps.maxVertexUniformBlocks;
1433 break;
1434 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1435 *params = mCaps.maxFragmentUniformBlocks;
1436 break;
1437 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1438 *params = mCaps.maxCombinedTextureImageUnits;
1439 break;
1440 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1441 *params = mCaps.maxVertexOutputComponents;
1442 break;
1443 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1444 *params = mCaps.maxFragmentInputComponents;
1445 break;
1446 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1447 *params = mCaps.minProgramTexelOffset;
1448 break;
1449 case GL_MAX_PROGRAM_TEXEL_OFFSET:
1450 *params = mCaps.maxProgramTexelOffset;
1451 break;
1452 case GL_MAJOR_VERSION:
1453 *params = getClientVersion().major;
1454 break;
1455 case GL_MINOR_VERSION:
1456 *params = getClientVersion().minor;
1457 break;
1458 case GL_MAX_ELEMENTS_INDICES:
1459 *params = mCaps.maxElementsIndices;
1460 break;
1461 case GL_MAX_ELEMENTS_VERTICES:
1462 *params = mCaps.maxElementsVertices;
1463 break;
1464 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1465 *params = mCaps.maxTransformFeedbackInterleavedComponents;
1466 break;
1467 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1468 *params = mCaps.maxTransformFeedbackSeparateAttributes;
1469 break;
1470 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1471 *params = mCaps.maxTransformFeedbackSeparateComponents;
1472 break;
1473 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1474 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1475 break;
1476 case GL_MAX_SAMPLES_ANGLE:
1477 *params = mCaps.maxSamples;
1478 break;
1479 case GL_MAX_VIEWPORT_DIMS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001480 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001481 params[0] = mCaps.maxViewportWidth;
1482 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 }
1484 break;
Jamie Madill231c7f52017-04-26 13:45:37 -04001485 case GL_COMPRESSED_TEXTURE_FORMATS:
1486 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(),
1487 params);
1488 break;
1489 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1490 *params = mResetStrategy;
1491 break;
1492 case GL_NUM_SHADER_BINARY_FORMATS:
1493 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
1494 break;
1495 case GL_SHADER_BINARY_FORMATS:
1496 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1497 break;
1498 case GL_NUM_PROGRAM_BINARY_FORMATS:
1499 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
1500 break;
1501 case GL_PROGRAM_BINARY_FORMATS:
1502 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
1503 break;
1504 case GL_NUM_EXTENSIONS:
1505 *params = static_cast<GLint>(mExtensionStrings.size());
1506 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001507
Jamie Madill231c7f52017-04-26 13:45:37 -04001508 // GL_KHR_debug
1509 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1510 *params = mExtensions.maxDebugMessageLength;
1511 break;
1512 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1513 *params = mExtensions.maxDebugLoggedMessages;
1514 break;
1515 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1516 *params = mExtensions.maxDebugGroupStackDepth;
1517 break;
1518 case GL_MAX_LABEL_LENGTH:
1519 *params = mExtensions.maxLabelLength;
1520 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001521
Jamie Madill231c7f52017-04-26 13:45:37 -04001522 // GL_EXT_disjoint_timer_query
1523 case GL_GPU_DISJOINT_EXT:
1524 *params = mImplementation->getGPUDisjoint();
1525 break;
1526 case GL_MAX_FRAMEBUFFER_WIDTH:
1527 *params = mCaps.maxFramebufferWidth;
1528 break;
1529 case GL_MAX_FRAMEBUFFER_HEIGHT:
1530 *params = mCaps.maxFramebufferHeight;
1531 break;
1532 case GL_MAX_FRAMEBUFFER_SAMPLES:
1533 *params = mCaps.maxFramebufferSamples;
1534 break;
1535 case GL_MAX_SAMPLE_MASK_WORDS:
1536 *params = mCaps.maxSampleMaskWords;
1537 break;
1538 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1539 *params = mCaps.maxColorTextureSamples;
1540 break;
1541 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1542 *params = mCaps.maxDepthTextureSamples;
1543 break;
1544 case GL_MAX_INTEGER_SAMPLES:
1545 *params = mCaps.maxIntegerSamples;
1546 break;
1547 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1548 *params = mCaps.maxVertexAttribRelativeOffset;
1549 break;
1550 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1551 *params = mCaps.maxVertexAttribBindings;
1552 break;
1553 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1554 *params = mCaps.maxVertexAttribStride;
1555 break;
1556 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1557 *params = mCaps.maxVertexAtomicCounterBuffers;
1558 break;
1559 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1560 *params = mCaps.maxVertexAtomicCounters;
1561 break;
1562 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1563 *params = mCaps.maxVertexImageUniforms;
1564 break;
1565 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1566 *params = mCaps.maxVertexShaderStorageBlocks;
1567 break;
1568 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1569 *params = mCaps.maxFragmentAtomicCounterBuffers;
1570 break;
1571 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1572 *params = mCaps.maxFragmentAtomicCounters;
1573 break;
1574 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1575 *params = mCaps.maxFragmentImageUniforms;
1576 break;
1577 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1578 *params = mCaps.maxFragmentShaderStorageBlocks;
1579 break;
1580 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1581 *params = mCaps.minProgramTextureGatherOffset;
1582 break;
1583 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1584 *params = mCaps.maxProgramTextureGatherOffset;
1585 break;
1586 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1587 *params = mCaps.maxComputeWorkGroupInvocations;
1588 break;
1589 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1590 *params = mCaps.maxComputeUniformBlocks;
1591 break;
1592 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1593 *params = mCaps.maxComputeTextureImageUnits;
1594 break;
1595 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1596 *params = mCaps.maxComputeSharedMemorySize;
1597 break;
1598 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1599 *params = mCaps.maxComputeUniformComponents;
1600 break;
1601 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1602 *params = mCaps.maxComputeAtomicCounterBuffers;
1603 break;
1604 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1605 *params = mCaps.maxComputeAtomicCounters;
1606 break;
1607 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1608 *params = mCaps.maxComputeImageUniforms;
1609 break;
1610 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1611 *params = mCaps.maxCombinedComputeUniformComponents;
1612 break;
1613 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1614 *params = mCaps.maxComputeShaderStorageBlocks;
1615 break;
1616 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1617 *params = mCaps.maxCombinedShaderOutputResources;
1618 break;
1619 case GL_MAX_UNIFORM_LOCATIONS:
1620 *params = mCaps.maxUniformLocations;
1621 break;
1622 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1623 *params = mCaps.maxAtomicCounterBufferBindings;
1624 break;
1625 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1626 *params = mCaps.maxAtomicCounterBufferSize;
1627 break;
1628 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1629 *params = mCaps.maxCombinedAtomicCounterBuffers;
1630 break;
1631 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1632 *params = mCaps.maxCombinedAtomicCounters;
1633 break;
1634 case GL_MAX_IMAGE_UNITS:
1635 *params = mCaps.maxImageUnits;
1636 break;
1637 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1638 *params = mCaps.maxCombinedImageUniforms;
1639 break;
1640 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1641 *params = mCaps.maxShaderStorageBufferBindings;
1642 break;
1643 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1644 *params = mCaps.maxCombinedShaderStorageBlocks;
1645 break;
1646 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1647 *params = mCaps.shaderStorageBufferOffsetAlignment;
1648 break;
1649 default:
1650 mGLState.getIntegerv(this, pname, params);
1651 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001652 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001653}
1654
Jamie Madill893ab082014-05-16 16:56:10 -04001655void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001656{
Shannon Woods53a94a82014-06-24 15:20:36 -04001657 // Queries about context capabilities and maximums are answered by Context.
1658 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001659 switch (pname)
1660 {
Jamie Madill231c7f52017-04-26 13:45:37 -04001661 case GL_MAX_ELEMENT_INDEX:
1662 *params = mCaps.maxElementIndex;
1663 break;
1664 case GL_MAX_UNIFORM_BLOCK_SIZE:
1665 *params = mCaps.maxUniformBlockSize;
1666 break;
1667 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1668 *params = mCaps.maxCombinedVertexUniformComponents;
1669 break;
1670 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1671 *params = mCaps.maxCombinedFragmentUniformComponents;
1672 break;
1673 case GL_MAX_SERVER_WAIT_TIMEOUT:
1674 *params = mCaps.maxServerWaitTimeout;
1675 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001676
Jamie Madill231c7f52017-04-26 13:45:37 -04001677 // GL_EXT_disjoint_timer_query
1678 case GL_TIMESTAMP_EXT:
1679 *params = mImplementation->getTimestamp();
1680 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001681
Jamie Madill231c7f52017-04-26 13:45:37 -04001682 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1683 *params = mCaps.maxShaderStorageBlockSize;
1684 break;
1685 default:
1686 UNREACHABLE();
1687 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001688 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001689}
1690
Geoff Lang70d0f492015-12-10 17:45:46 -05001691void Context::getPointerv(GLenum pname, void **params) const
1692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001693 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001694}
1695
Martin Radev66fb8202016-07-28 11:45:20 +03001696void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001697{
Shannon Woods53a94a82014-06-24 15:20:36 -04001698 // Queries about context capabilities and maximums are answered by Context.
1699 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001700
1701 GLenum nativeType;
1702 unsigned int numParams;
1703 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1704 ASSERT(queryStatus);
1705
1706 if (nativeType == GL_INT)
1707 {
1708 switch (target)
1709 {
1710 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1711 ASSERT(index < 3u);
1712 *data = mCaps.maxComputeWorkGroupCount[index];
1713 break;
1714 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1715 ASSERT(index < 3u);
1716 *data = mCaps.maxComputeWorkGroupSize[index];
1717 break;
1718 default:
1719 mGLState.getIntegeri_v(target, index, data);
1720 }
1721 }
1722 else
1723 {
1724 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1725 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001726}
1727
Martin Radev66fb8202016-07-28 11:45:20 +03001728void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001729{
Shannon Woods53a94a82014-06-24 15:20:36 -04001730 // Queries about context capabilities and maximums are answered by Context.
1731 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001732
1733 GLenum nativeType;
1734 unsigned int numParams;
1735 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1736 ASSERT(queryStatus);
1737
1738 if (nativeType == GL_INT_64_ANGLEX)
1739 {
1740 mGLState.getInteger64i_v(target, index, data);
1741 }
1742 else
1743 {
1744 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1745 }
1746}
1747
1748void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1749{
1750 // Queries about context capabilities and maximums are answered by Context.
1751 // Queries about current GL state values are answered by State.
1752
1753 GLenum nativeType;
1754 unsigned int numParams;
1755 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1756 ASSERT(queryStatus);
1757
1758 if (nativeType == GL_BOOL)
1759 {
1760 mGLState.getBooleani_v(target, index, data);
1761 }
1762 else
1763 {
1764 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1765 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001766}
1767
He Yunchao010e4db2017-03-03 14:22:06 +08001768void Context::getBufferParameteriv(GLenum target, GLenum pname, GLint *params)
1769{
1770 Buffer *buffer = mGLState.getTargetBuffer(target);
1771 QueryBufferParameteriv(buffer, pname, params);
1772}
1773
1774void Context::getFramebufferAttachmentParameteriv(GLenum target,
1775 GLenum attachment,
1776 GLenum pname,
1777 GLint *params)
1778{
1779 const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
1780 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1781}
1782
1783void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
1784{
1785 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
1786 QueryRenderbufferiv(this, renderbuffer, pname, params);
1787}
1788
1789void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
1790{
1791 Texture *texture = getTargetTexture(target);
1792 QueryTexParameterfv(texture, pname, params);
1793}
1794
1795void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params)
1796{
1797 Texture *texture = getTargetTexture(target);
1798 QueryTexParameteriv(texture, pname, params);
1799}
1800void Context::texParameterf(GLenum target, GLenum pname, GLfloat param)
1801{
1802 Texture *texture = getTargetTexture(target);
1803 SetTexParameterf(texture, pname, param);
1804}
1805
1806void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1807{
1808 Texture *texture = getTargetTexture(target);
1809 SetTexParameterfv(texture, pname, params);
1810}
1811
1812void Context::texParameteri(GLenum target, GLenum pname, GLint param)
1813{
1814 Texture *texture = getTargetTexture(target);
1815 SetTexParameteri(texture, pname, param);
1816}
1817
1818void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params)
1819{
1820 Texture *texture = getTargetTexture(target);
1821 SetTexParameteriv(texture, pname, params);
1822}
1823
Jamie Madill675fe712016-12-19 13:07:54 -05001824void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001825{
Jamie Madill1b94d432015-08-07 13:23:23 -04001826 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001827 auto error = mImplementation->drawArrays(mode, first, count);
1828 handleError(error);
1829 if (!error.isError())
1830 {
1831 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1832 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833}
1834
Jamie Madill675fe712016-12-19 13:07:54 -05001835void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001836{
1837 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001838 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1839 handleError(error);
1840 if (!error.isError())
1841 {
1842 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1843 }
Geoff Langf6db0982015-08-25 13:04:00 -04001844}
1845
Jamie Madill876429b2017-04-20 15:46:24 -04001846void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847{
Jamie Madill1b94d432015-08-07 13:23:23 -04001848 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001849 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001850 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001851}
1852
Jamie Madill675fe712016-12-19 13:07:54 -05001853void Context::drawElementsInstanced(GLenum mode,
1854 GLsizei count,
1855 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001856 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001857 GLsizei instances)
Geoff Langf6db0982015-08-25 13:04:00 -04001858{
1859 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001860 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001861 handleError(
1862 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001863}
1864
Jamie Madill675fe712016-12-19 13:07:54 -05001865void Context::drawRangeElements(GLenum mode,
1866 GLuint start,
1867 GLuint end,
1868 GLsizei count,
1869 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04001870 const void *indices)
Geoff Langf6db0982015-08-25 13:04:00 -04001871{
1872 syncRendererState();
Jamie Madill9c9b40a2017-04-26 16:31:57 -04001873 const IndexRange &indexRange = getParams<HasIndexRange>().getIndexRange().value();
Jamie Madill675fe712016-12-19 13:07:54 -05001874 handleError(
1875 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001876}
1877
Jamie Madill876429b2017-04-20 15:46:24 -04001878void Context::drawArraysIndirect(GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001879{
1880 syncRendererState();
1881 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1882}
1883
Jamie Madill876429b2017-04-20 15:46:24 -04001884void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +08001885{
1886 syncRendererState();
1887 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1888}
1889
Jamie Madill675fe712016-12-19 13:07:54 -05001890void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001891{
Jamie Madill675fe712016-12-19 13:07:54 -05001892 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001893}
1894
Jamie Madill675fe712016-12-19 13:07:54 -05001895void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001896{
Jamie Madill675fe712016-12-19 13:07:54 -05001897 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001898}
1899
Austin Kinross6ee1e782015-05-29 17:05:37 -07001900void Context::insertEventMarker(GLsizei length, const char *marker)
1901{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001902 ASSERT(mImplementation);
1903 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001904}
1905
1906void Context::pushGroupMarker(GLsizei length, const char *marker)
1907{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001908 ASSERT(mImplementation);
1909 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001910}
1911
1912void Context::popGroupMarker()
1913{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001914 ASSERT(mImplementation);
1915 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001916}
1917
Geoff Langd8605522016-04-13 10:19:12 -04001918void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1919{
1920 Program *programObject = getProgram(program);
1921 ASSERT(programObject);
1922
1923 programObject->bindUniformLocation(location, name);
1924}
1925
Sami Väisänena797e062016-05-12 15:23:40 +03001926void Context::setCoverageModulation(GLenum components)
1927{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001928 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001929}
1930
Sami Väisänene45e53b2016-05-25 10:36:04 +03001931void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1932{
1933 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1934}
1935
1936void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1937{
1938 GLfloat I[16];
1939 angle::Matrix<GLfloat>::setToIdentity(I);
1940
1941 mGLState.loadPathRenderingMatrix(matrixMode, I);
1942}
1943
1944void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1945{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001946 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001947 if (!pathObj)
1948 return;
1949
1950 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1951 syncRendererState();
1952
1953 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1954}
1955
1956void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1957{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001958 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001959 if (!pathObj)
1960 return;
1961
1962 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1963 syncRendererState();
1964
1965 mImplementation->stencilStrokePath(pathObj, reference, mask);
1966}
1967
1968void Context::coverFillPath(GLuint path, GLenum coverMode)
1969{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001970 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001971 if (!pathObj)
1972 return;
1973
1974 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1975 syncRendererState();
1976
1977 mImplementation->coverFillPath(pathObj, coverMode);
1978}
1979
1980void Context::coverStrokePath(GLuint path, GLenum coverMode)
1981{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001982 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001983 if (!pathObj)
1984 return;
1985
1986 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1987 syncRendererState();
1988
1989 mImplementation->coverStrokePath(pathObj, coverMode);
1990}
1991
1992void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1993{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001994 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001995 if (!pathObj)
1996 return;
1997
1998 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1999 syncRendererState();
2000
2001 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
2002}
2003
2004void Context::stencilThenCoverStrokePath(GLuint path,
2005 GLint reference,
2006 GLuint mask,
2007 GLenum coverMode)
2008{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002009 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03002010 if (!pathObj)
2011 return;
2012
2013 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2014 syncRendererState();
2015
2016 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
2017}
2018
Sami Väisänend59ca052016-06-21 16:10:00 +03002019void Context::coverFillPathInstanced(GLsizei numPaths,
2020 GLenum pathNameType,
2021 const void *paths,
2022 GLuint pathBase,
2023 GLenum coverMode,
2024 GLenum transformType,
2025 const GLfloat *transformValues)
2026{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002027 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002028
2029 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2030 syncRendererState();
2031
2032 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
2033}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002034
Sami Väisänend59ca052016-06-21 16:10:00 +03002035void Context::coverStrokePathInstanced(GLsizei numPaths,
2036 GLenum pathNameType,
2037 const void *paths,
2038 GLuint pathBase,
2039 GLenum coverMode,
2040 GLenum transformType,
2041 const GLfloat *transformValues)
2042{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002043 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002044
2045 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2046 syncRendererState();
2047
2048 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
2049 transformValues);
2050}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002051
Sami Väisänend59ca052016-06-21 16:10:00 +03002052void Context::stencilFillPathInstanced(GLsizei numPaths,
2053 GLenum pathNameType,
2054 const void *paths,
2055 GLuint pathBase,
2056 GLenum fillMode,
2057 GLuint mask,
2058 GLenum transformType,
2059 const GLfloat *transformValues)
2060{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002061 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002062
2063 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2064 syncRendererState();
2065
2066 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
2067 transformValues);
2068}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002069
Sami Väisänend59ca052016-06-21 16:10:00 +03002070void Context::stencilStrokePathInstanced(GLsizei numPaths,
2071 GLenum pathNameType,
2072 const void *paths,
2073 GLuint pathBase,
2074 GLint reference,
2075 GLuint mask,
2076 GLenum transformType,
2077 const GLfloat *transformValues)
2078{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002079 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002080
2081 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2082 syncRendererState();
2083
2084 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
2085 transformValues);
2086}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002087
Sami Väisänend59ca052016-06-21 16:10:00 +03002088void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
2089 GLenum pathNameType,
2090 const void *paths,
2091 GLuint pathBase,
2092 GLenum fillMode,
2093 GLuint mask,
2094 GLenum coverMode,
2095 GLenum transformType,
2096 const GLfloat *transformValues)
2097{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002098 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002099
2100 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2101 syncRendererState();
2102
2103 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
2104 transformType, transformValues);
2105}
Sami Väisänen46eaa942016-06-29 10:26:37 +03002106
Sami Väisänend59ca052016-06-21 16:10:00 +03002107void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
2108 GLenum pathNameType,
2109 const void *paths,
2110 GLuint pathBase,
2111 GLint reference,
2112 GLuint mask,
2113 GLenum coverMode,
2114 GLenum transformType,
2115 const GLfloat *transformValues)
2116{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002117 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03002118
2119 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
2120 syncRendererState();
2121
2122 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
2123 transformType, transformValues);
2124}
2125
Sami Väisänen46eaa942016-06-29 10:26:37 +03002126void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
2127{
2128 auto *programObject = getProgram(program);
2129
2130 programObject->bindFragmentInputLocation(location, name);
2131}
2132
2133void Context::programPathFragmentInputGen(GLuint program,
2134 GLint location,
2135 GLenum genMode,
2136 GLint components,
2137 const GLfloat *coeffs)
2138{
2139 auto *programObject = getProgram(program);
2140
2141 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
2142}
2143
jchen1015015f72017-03-16 13:54:21 +08002144GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
2145{
jchen10fd7c3b52017-03-21 15:36:03 +08002146 const auto *programObject = getProgram(program);
jchen1015015f72017-03-16 13:54:21 +08002147 return QueryProgramResourceIndex(programObject, programInterface, name);
2148}
2149
jchen10fd7c3b52017-03-21 15:36:03 +08002150void Context::getProgramResourceName(GLuint program,
2151 GLenum programInterface,
2152 GLuint index,
2153 GLsizei bufSize,
2154 GLsizei *length,
2155 GLchar *name)
2156{
2157 const auto *programObject = getProgram(program);
2158 QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
2159}
2160
Jamie Madill437fa652016-05-03 15:13:24 -04002161void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002162{
Geoff Langda5777c2014-07-11 09:52:58 -04002163 if (error.isError())
2164 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002165 GLenum code = error.getCode();
2166 mErrors.insert(code);
2167 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
2168 {
2169 markContextLost();
2170 }
Geoff Lang70d0f492015-12-10 17:45:46 -05002171
2172 if (!error.getMessage().empty())
2173 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 auto *debug = &mGLState.getDebug();
2175 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
2176 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 }
Geoff Langda5777c2014-07-11 09:52:58 -04002178 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002179}
2180
2181// Get one of the recorded errors and clear its flag, if any.
2182// [OpenGL ES 2.0.24] section 2.5 page 13.
2183GLenum Context::getError()
2184{
Geoff Langda5777c2014-07-11 09:52:58 -04002185 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002186 {
Geoff Langda5777c2014-07-11 09:52:58 -04002187 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188 }
Geoff Langda5777c2014-07-11 09:52:58 -04002189 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002190 {
Geoff Langda5777c2014-07-11 09:52:58 -04002191 GLenum error = *mErrors.begin();
2192 mErrors.erase(mErrors.begin());
2193 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002194 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195}
2196
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002197// NOTE: this function should not assume that this context is current!
2198void Context::markContextLost()
2199{
2200 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002201 {
Jamie Madill231c7f52017-04-26 13:45:37 -04002202 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002203 mContextLostForced = true;
2204 }
Jamie Madill231c7f52017-04-26 13:45:37 -04002205 mContextLost = true;
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002206}
2207
2208bool Context::isContextLost()
2209{
2210 return mContextLost;
2211}
2212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002213GLenum Context::getResetStatus()
2214{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002215 // Even if the application doesn't want to know about resets, we want to know
2216 // as it will allow us to skip all the calls.
2217 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002218 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002219 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002220 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002221 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002222 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002223
2224 // EXT_robustness, section 2.6: If the reset notification behavior is
2225 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2226 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2227 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002228 }
2229
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002230 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2231 // status should be returned at least once, and GL_NO_ERROR should be returned
2232 // once the device has finished resetting.
2233 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002235 ASSERT(mResetStatus == GL_NO_ERROR);
2236 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002237
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002238 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002239 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002240 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002241 }
2242 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002243 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002244 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002245 // If markContextLost was used to mark the context lost then
2246 // assume that is not recoverable, and continue to report the
2247 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002248 mResetStatus = mImplementation->getResetStatus();
2249 }
Jamie Madill893ab082014-05-16 16:56:10 -04002250
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002251 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252}
2253
2254bool Context::isResetNotificationEnabled()
2255{
2256 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2257}
2258
Corentin Walleze3b10e82015-05-20 11:06:25 -04002259const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002260{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002261 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002262}
2263
2264EGLenum Context::getClientType() const
2265{
2266 return mClientType;
2267}
2268
2269EGLenum Context::getRenderBuffer() const
2270{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002271 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2272 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002273 {
2274 return EGL_NONE;
2275 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002276
2277 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2278 ASSERT(backAttachment != nullptr);
2279 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002280}
2281
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002282VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002283{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002284 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002285 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2286 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002287 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002288 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle,
2289 mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002290
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002291 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002292 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002293
2294 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002295}
2296
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002297TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002298{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002299 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002300 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2301 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002302 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002303 transformFeedback =
2304 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002305 transformFeedback->addRef();
2306 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002307 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002308
2309 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002310}
2311
2312bool Context::isVertexArrayGenerated(GLuint vertexArray)
2313{
Geoff Langf41a7152016-09-19 15:11:17 -04002314 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002315 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2316}
2317
2318bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2319{
Geoff Langf41a7152016-09-19 15:11:17 -04002320 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002321 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2322}
2323
Shannon Woods53a94a82014-06-24 15:20:36 -04002324void Context::detachTexture(GLuint texture)
2325{
2326 // Simple pass-through to State's detachTexture method, as textures do not require
2327 // allocation map management either here or in the resource manager at detach time.
2328 // Zero textures are held by the Context, and we don't attempt to request them from
2329 // the State.
Jamie Madilla02315b2017-02-23 14:14:47 -05002330 mGLState.detachTexture(this, mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002331}
2332
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002333void Context::detachBuffer(GLuint buffer)
2334{
Yuly Novikov5807a532015-12-03 13:01:22 -05002335 // Simple pass-through to State's detachBuffer method, since
2336 // only buffer attachments to container objects that are bound to the current context
2337 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002338
Yuly Novikov5807a532015-12-03 13:01:22 -05002339 // [OpenGL ES 3.2] section 5.1.2 page 45:
2340 // Attachments to unbound container objects, such as
2341 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2342 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002343 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002344}
2345
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002346void Context::detachFramebuffer(GLuint framebuffer)
2347{
Shannon Woods53a94a82014-06-24 15:20:36 -04002348 // Framebuffer detachment is handled by Context, because 0 is a valid
2349 // Framebuffer object, and a pointer to it must be passed from Context
2350 // to State at binding time.
2351
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002352 // [OpenGL ES 2.0.24] section 4.4 page 107:
Jamie Madill231c7f52017-04-26 13:45:37 -04002353 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
2354 // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
2355 // zero.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002356
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002357 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002358 {
2359 bindReadFramebuffer(0);
2360 }
2361
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002362 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002363 {
2364 bindDrawFramebuffer(0);
2365 }
2366}
2367
2368void Context::detachRenderbuffer(GLuint renderbuffer)
2369{
Jamie Madilla02315b2017-02-23 14:14:47 -05002370 mGLState.detachRenderbuffer(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002371}
2372
Jamie Madill57a89722013-07-02 11:57:03 -04002373void Context::detachVertexArray(GLuint vertexArray)
2374{
Jamie Madill77a72f62015-04-14 11:18:32 -04002375 // Vertex array detachment is handled by Context, because 0 is a valid
2376 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002377 // binding time.
2378
Jamie Madill57a89722013-07-02 11:57:03 -04002379 // [OpenGL ES 3.0.2] section 2.10 page 43:
2380 // If a vertex array object that is currently bound is deleted, the binding
2381 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002382 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002383 {
2384 bindVertexArray(0);
2385 }
2386}
2387
Geoff Langc8058452014-02-03 12:04:11 -05002388void Context::detachTransformFeedback(GLuint transformFeedback)
2389{
Corentin Walleza2257da2016-04-19 16:43:12 -04002390 // Transform feedback detachment is handled by Context, because 0 is a valid
2391 // transform feedback, and a pointer to it must be passed from Context to State at
2392 // binding time.
2393
2394 // The OpenGL specification doesn't mention what should happen when the currently bound
2395 // transform feedback object is deleted. Since it is a container object, we treat it like
2396 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002397 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002398 {
2399 bindTransformFeedback(0);
2400 }
Geoff Langc8058452014-02-03 12:04:11 -05002401}
2402
Jamie Madilldc356042013-07-19 16:36:57 -04002403void Context::detachSampler(GLuint sampler)
2404{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002405 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002406}
2407
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002408void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2409{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002410 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002411}
2412
Jamie Madille29d1672013-07-19 16:36:57 -04002413void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2414{
Geoff Langc1984ed2016-10-07 12:41:00 -04002415 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002416 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002417 SetSamplerParameteri(samplerObject, pname, param);
2418}
Jamie Madille29d1672013-07-19 16:36:57 -04002419
Geoff Langc1984ed2016-10-07 12:41:00 -04002420void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2421{
2422 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002423 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002424 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002425}
2426
2427void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2428{
Geoff Langc1984ed2016-10-07 12:41:00 -04002429 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002430 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002431 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002432}
2433
Geoff Langc1984ed2016-10-07 12:41:00 -04002434void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002435{
Geoff Langc1984ed2016-10-07 12:41:00 -04002436 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002437 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002438 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002439}
2440
Geoff Langc1984ed2016-10-07 12:41:00 -04002441void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002442{
Geoff Langc1984ed2016-10-07 12:41:00 -04002443 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002444 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002445 QuerySamplerParameteriv(samplerObject, pname, params);
2446}
Jamie Madill9675b802013-07-19 16:36:59 -04002447
Geoff Langc1984ed2016-10-07 12:41:00 -04002448void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2449{
2450 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002451 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002452 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002453}
2454
Olli Etuahof0fee072016-03-30 15:11:58 +03002455void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2456{
2457 gl::Program *programObject = getProgram(program);
Yunchao He61afff12017-03-14 15:34:03 +08002458 SetProgramParameteri(programObject, pname, value);
Olli Etuahof0fee072016-03-30 15:11:58 +03002459}
2460
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002461void Context::initRendererString()
2462{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002463 std::ostringstream rendererString;
2464 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002465 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002466 rendererString << ")";
2467
Geoff Langcec35902014-04-16 10:52:36 -04002468 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002469}
2470
Geoff Langc339c4e2016-11-29 10:37:36 -05002471void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002472{
Geoff Langc339c4e2016-11-29 10:37:36 -05002473 const Version &clientVersion = getClientVersion();
2474
2475 std::ostringstream versionString;
2476 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2477 << ANGLE_VERSION_STRING << ")";
2478 mVersionString = MakeStaticString(versionString.str());
2479
2480 std::ostringstream shadingLanguageVersionString;
2481 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2482 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2483 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2484 << ")";
2485 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002486}
2487
Geoff Langcec35902014-04-16 10:52:36 -04002488void Context::initExtensionStrings()
2489{
Geoff Langc339c4e2016-11-29 10:37:36 -05002490 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2491 std::ostringstream combinedStringStream;
2492 std::copy(strings.begin(), strings.end(),
2493 std::ostream_iterator<const char *>(combinedStringStream, " "));
2494 return MakeStaticString(combinedStringStream.str());
2495 };
2496
2497 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002498 for (const auto &extensionString : mExtensions.getStrings())
2499 {
2500 mExtensionStrings.push_back(MakeStaticString(extensionString));
2501 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002502 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002503
Bryan Bernhart58806562017-01-05 13:09:31 -08002504 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2505
Geoff Langc339c4e2016-11-29 10:37:36 -05002506 mRequestableExtensionStrings.clear();
2507 for (const auto &extensionInfo : GetExtensionInfoMap())
2508 {
2509 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002510 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2511 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002512 {
2513 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2514 }
2515 }
2516 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002517}
2518
Geoff Langc339c4e2016-11-29 10:37:36 -05002519const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002520{
Geoff Langc339c4e2016-11-29 10:37:36 -05002521 switch (name)
2522 {
2523 case GL_VENDOR:
2524 return reinterpret_cast<const GLubyte *>("Google Inc.");
2525
2526 case GL_RENDERER:
2527 return reinterpret_cast<const GLubyte *>(mRendererString);
2528
2529 case GL_VERSION:
2530 return reinterpret_cast<const GLubyte *>(mVersionString);
2531
2532 case GL_SHADING_LANGUAGE_VERSION:
2533 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2534
2535 case GL_EXTENSIONS:
2536 return reinterpret_cast<const GLubyte *>(mExtensionString);
2537
2538 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2539 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2540
2541 default:
2542 UNREACHABLE();
2543 return nullptr;
2544 }
Geoff Langcec35902014-04-16 10:52:36 -04002545}
2546
Geoff Langc339c4e2016-11-29 10:37:36 -05002547const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002548{
Geoff Langc339c4e2016-11-29 10:37:36 -05002549 switch (name)
2550 {
2551 case GL_EXTENSIONS:
2552 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2553
2554 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2555 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2556
2557 default:
2558 UNREACHABLE();
2559 return nullptr;
2560 }
Geoff Langcec35902014-04-16 10:52:36 -04002561}
2562
2563size_t Context::getExtensionStringCount() const
2564{
2565 return mExtensionStrings.size();
2566}
2567
Geoff Langc339c4e2016-11-29 10:37:36 -05002568void Context::requestExtension(const char *name)
2569{
2570 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2571 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2572 const auto &extension = extensionInfos.at(name);
2573 ASSERT(extension.Requestable);
2574
2575 if (mExtensions.*(extension.ExtensionsMember))
2576 {
2577 // Extension already enabled
2578 return;
2579 }
2580
2581 mExtensions.*(extension.ExtensionsMember) = true;
2582 updateCaps();
2583 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002584
2585 // Re-create the compiler with the requested extensions enabled.
2586 SafeDelete(mCompiler);
2587 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Lang9aded172017-04-05 11:07:56 -04002588
2589 // Invalidate all cached completenesses for textures and framebuffer. Some extensions make new
2590 // formats renderable or sampleable.
2591 mState.mTextures->invalidateTextureComplenessCache();
2592 for (auto &zeroTexture : mZeroTextures)
2593 {
2594 zeroTexture.second->invalidateCompletenessCache();
2595 }
2596
2597 mState.mFramebuffers->invalidateFramebufferComplenessCache();
Geoff Langc339c4e2016-11-29 10:37:36 -05002598}
2599
2600size_t Context::getRequestableExtensionStringCount() const
2601{
2602 return mRequestableExtensionStrings.size();
2603}
2604
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002605void Context::beginTransformFeedback(GLenum primitiveMode)
2606{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002607 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002608 ASSERT(transformFeedback != nullptr);
2609 ASSERT(!transformFeedback->isPaused());
2610
Jamie Madill6c1f6712017-02-14 19:08:04 -05002611 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002612}
2613
2614bool Context::hasActiveTransformFeedback(GLuint program) const
2615{
2616 for (auto pair : mTransformFeedbackMap)
2617 {
2618 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2619 {
2620 return true;
2621 }
2622 }
2623 return false;
2624}
2625
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002626void Context::initCaps(const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002627{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002628 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002629
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002630 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002631
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002632 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002633
Geoff Langeb66a6e2016-10-31 13:06:12 -04002634 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002635 {
2636 // Disable ES3+ extensions
Jamie Madill231c7f52017-04-26 13:45:37 -04002637 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002638 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002639 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002640 }
2641
Geoff Langeb66a6e2016-10-31 13:06:12 -04002642 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002643 {
2644 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
Jamie Madill231c7f52017-04-26 13:45:37 -04002645 // mExtensions.sRGB = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002646 }
2647
Jamie Madill00ed7a12016-05-19 13:13:38 -04002648 // Some extensions are always available because they are implemented in the GL layer.
Jamie Madill231c7f52017-04-26 13:45:37 -04002649 mExtensions.bindUniformLocation = true;
2650 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002651 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002652 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002653 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002654
2655 // Enable the no error extension if the context was created with the flag.
2656 mExtensions.noError = mSkipValidation;
2657
Corentin Wallezccab69d2017-01-27 16:57:15 -05002658 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002659 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002660
Geoff Lang70d0f492015-12-10 17:45:46 -05002661 // Explicitly enable GL_KHR_debug
2662 mExtensions.debug = true;
2663 mExtensions.maxDebugMessageLength = 1024;
2664 mExtensions.maxDebugLoggedMessages = 1024;
2665 mExtensions.maxDebugGroupStackDepth = 1024;
2666 mExtensions.maxLabelLength = 1024;
2667
Geoff Langff5b2d52016-09-07 11:32:23 -04002668 // Explicitly enable GL_ANGLE_robust_client_memory
2669 mExtensions.robustClientMemory = true;
2670
Jamie Madille08a1d32017-03-07 17:24:06 -05002671 // Determine robust resource init availability from EGL.
2672 mExtensions.robustResourceInitialization =
2673 displayExtensions.createContextRobustResourceInitialization;
2674
Geoff Lang301d1612014-07-09 10:34:37 -04002675 // Apply implementation limits
2676 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002677 mCaps.maxVertexAttribBindings =
2678 getClientVersion() < ES_3_1
2679 ? mCaps.maxVertexAttributes
2680 : std::min<GLuint>(mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
2681
Jamie Madill231c7f52017-04-26 13:45:37 -04002682 mCaps.maxVertexUniformBlocks = std::min<GLuint>(
2683 mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2684 mCaps.maxVertexOutputComponents =
2685 std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang301d1612014-07-09 10:34:37 -04002686
Jamie Madill231c7f52017-04-26 13:45:37 -04002687 mCaps.maxFragmentInputComponents =
2688 std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002689
Geoff Langc287ea62016-09-16 14:46:51 -04002690 // WebGL compatibility
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002691 mExtensions.webglCompatibility = mWebGLContext;
Geoff Langc287ea62016-09-16 14:46:51 -04002692 for (const auto &extensionInfo : GetExtensionInfoMap())
2693 {
2694 // If this context is for WebGL, disable all enableable extensions
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002695 if (mWebGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002696 {
2697 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2698 }
2699 }
2700
2701 // Generate texture caps
2702 updateCaps();
2703}
2704
2705void Context::updateCaps()
2706{
Geoff Lang900013c2014-07-07 11:32:19 -04002707 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002708 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002709
Jamie Madill4e0e6f82017-02-17 11:06:03 -05002710 for (auto capsIt : mImplementation->getNativeTextureCaps())
Geoff Lang493daf52014-07-03 13:38:44 -04002711 {
Geoff Langca271392017-04-05 12:30:00 -04002712 GLenum sizedInternalFormat = capsIt.first;
Jamie Madill231c7f52017-04-26 13:45:37 -04002713 TextureCaps formatCaps = capsIt.second;
Geoff Lang493daf52014-07-03 13:38:44 -04002714
Geoff Langca271392017-04-05 12:30:00 -04002715 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002716
Geoff Lang0d8b7242015-09-09 14:56:53 -04002717 // Update the format caps based on the client version and extensions.
2718 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2719 // ES3.
2720 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002721 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002722 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002723 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002724 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002725 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002726
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002727 // OpenGL ES does not support multisampling with non-rendererable formats
2728 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2729 if (!formatInfo.renderSupport ||
2730 (getClientVersion() < ES_3_1 &&
2731 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002732 {
Geoff Langd87878e2014-09-19 15:42:59 -04002733 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002734 }
Geoff Langd87878e2014-09-19 15:42:59 -04002735
2736 if (formatCaps.texturable && formatInfo.compressed)
2737 {
Geoff Langca271392017-04-05 12:30:00 -04002738 mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
Geoff Langd87878e2014-09-19 15:42:59 -04002739 }
2740
Geoff Langca271392017-04-05 12:30:00 -04002741 mTextureCaps.insert(sizedInternalFormat, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002742 }
2743}
2744
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002745void Context::initWorkarounds()
2746{
2747 // Lose the context upon out of memory error if the application is
2748 // expecting to watch for those events.
2749 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2750}
2751
Jamie Madill1b94d432015-08-07 13:23:23 -04002752void Context::syncRendererState()
2753{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002754 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
Frank Henigman5a53d542017-02-16 21:24:10 -05002755 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 mGLState.clearDirtyBits();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002757 mGLState.syncDirtyObjects(this);
Jamie Madill1b94d432015-08-07 13:23:23 -04002758}
2759
Jamie Madillad9f24e2016-02-12 09:27:24 -05002760void Context::syncRendererState(const State::DirtyBits &bitMask,
2761 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002762{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
Frank Henigman5a53d542017-02-16 21:24:10 -05002764 mImplementation->syncState(dirtyBits);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 mGLState.clearDirtyBits(dirtyBits);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002766 mGLState.syncDirtyObjects(this, objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002767}
Jamie Madillc29968b2016-01-20 11:17:23 -05002768
2769void Context::blitFramebuffer(GLint srcX0,
2770 GLint srcY0,
2771 GLint srcX1,
2772 GLint srcY1,
2773 GLint dstX0,
2774 GLint dstY0,
2775 GLint dstX1,
2776 GLint dstY1,
2777 GLbitfield mask,
2778 GLenum filter)
2779{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002781 ASSERT(drawFramebuffer);
2782
2783 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2784 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2785
Jamie Madillad9f24e2016-02-12 09:27:24 -05002786 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002787
Jamie Madill8415b5f2016-04-26 13:41:39 -04002788 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002789}
Jamie Madillc29968b2016-01-20 11:17:23 -05002790
2791void Context::clear(GLbitfield mask)
2792{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002793 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002795}
2796
2797void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2798{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002799 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2801 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002802}
2803
2804void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2805{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002806 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002807 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2808 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002809}
2810
2811void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2812{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002813 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2815 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002816}
2817
2818void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2819{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002820 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002821 ASSERT(framebufferObject);
2822
2823 // If a buffer is not present, the clear has no effect
2824 if (framebufferObject->getDepthbuffer() == nullptr &&
2825 framebufferObject->getStencilbuffer() == nullptr)
2826 {
2827 return;
2828 }
2829
Jamie Madillad9f24e2016-02-12 09:27:24 -05002830 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002831 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2832 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002833}
2834
2835void Context::readPixels(GLint x,
2836 GLint y,
2837 GLsizei width,
2838 GLsizei height,
2839 GLenum format,
2840 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002841 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05002842{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002843 if (width == 0 || height == 0)
2844 {
2845 return;
2846 }
2847
Jamie Madillad9f24e2016-02-12 09:27:24 -05002848 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002849
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002851 ASSERT(framebufferObject);
2852
2853 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002854 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002855}
2856
2857void Context::copyTexImage2D(GLenum target,
2858 GLint level,
2859 GLenum internalformat,
2860 GLint x,
2861 GLint y,
2862 GLsizei width,
2863 GLsizei height,
2864 GLint border)
2865{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002866 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002867 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002868
Jamie Madillc29968b2016-01-20 11:17:23 -05002869 Rectangle sourceArea(x, y, width, height);
2870
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002871 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002872 Texture *texture =
2873 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002874 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002875}
2876
2877void Context::copyTexSubImage2D(GLenum target,
2878 GLint level,
2879 GLint xoffset,
2880 GLint yoffset,
2881 GLint x,
2882 GLint y,
2883 GLsizei width,
2884 GLsizei height)
2885{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002886 if (width == 0 || height == 0)
2887 {
2888 return;
2889 }
2890
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002891 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002892 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002893
Jamie Madillc29968b2016-01-20 11:17:23 -05002894 Offset destOffset(xoffset, yoffset, 0);
2895 Rectangle sourceArea(x, y, width, height);
2896
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002898 Texture *texture =
2899 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002900 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002901}
2902
2903void Context::copyTexSubImage3D(GLenum target,
2904 GLint level,
2905 GLint xoffset,
2906 GLint yoffset,
2907 GLint zoffset,
2908 GLint x,
2909 GLint y,
2910 GLsizei width,
2911 GLsizei height)
2912{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002913 if (width == 0 || height == 0)
2914 {
2915 return;
2916 }
2917
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002918 // Only sync the read FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002919 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002920
Jamie Madillc29968b2016-01-20 11:17:23 -05002921 Offset destOffset(xoffset, yoffset, zoffset);
2922 Rectangle sourceArea(x, y, width, height);
2923
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002924 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002925 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002926 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002927}
2928
2929void Context::framebufferTexture2D(GLenum target,
2930 GLenum attachment,
2931 GLenum textarget,
2932 GLuint texture,
2933 GLint level)
2934{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002935 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002936 ASSERT(framebuffer);
2937
2938 if (texture != 0)
2939 {
2940 Texture *textureObj = getTexture(texture);
2941
2942 ImageIndex index = ImageIndex::MakeInvalid();
2943
2944 if (textarget == GL_TEXTURE_2D)
2945 {
2946 index = ImageIndex::Make2D(level);
2947 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002948 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2949 {
2950 ASSERT(level == 0);
2951 index = ImageIndex::Make2DMultisample();
2952 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002953 else
2954 {
2955 ASSERT(IsCubeMapTextureTarget(textarget));
2956 index = ImageIndex::MakeCube(textarget, level);
2957 }
2958
Jamie Madilla02315b2017-02-23 14:14:47 -05002959 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
Jamie Madillc29968b2016-01-20 11:17:23 -05002960 }
2961 else
2962 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002963 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002964 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002965
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002967}
2968
2969void Context::framebufferRenderbuffer(GLenum target,
2970 GLenum attachment,
2971 GLenum renderbuffertarget,
2972 GLuint renderbuffer)
2973{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002974 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002975 ASSERT(framebuffer);
2976
2977 if (renderbuffer != 0)
2978 {
2979 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
Jamie Madilla02315b2017-02-23 14:14:47 -05002980
2981 framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
Jamie Madillc29968b2016-01-20 11:17:23 -05002982 renderbufferObject);
2983 }
2984 else
2985 {
Jamie Madilla02315b2017-02-23 14:14:47 -05002986 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05002987 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002988
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002989 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002990}
2991
2992void Context::framebufferTextureLayer(GLenum target,
2993 GLenum attachment,
2994 GLuint texture,
2995 GLint level,
2996 GLint layer)
2997{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002998 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002999 ASSERT(framebuffer);
3000
3001 if (texture != 0)
3002 {
3003 Texture *textureObject = getTexture(texture);
3004
3005 ImageIndex index = ImageIndex::MakeInvalid();
3006
3007 if (textureObject->getTarget() == GL_TEXTURE_3D)
3008 {
3009 index = ImageIndex::Make3D(level, layer);
3010 }
3011 else
3012 {
3013 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
3014 index = ImageIndex::Make2DArray(level, layer);
3015 }
3016
Jamie Madilla02315b2017-02-23 14:14:47 -05003017 framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
Jamie Madillc29968b2016-01-20 11:17:23 -05003018 }
3019 else
3020 {
Jamie Madilla02315b2017-02-23 14:14:47 -05003021 framebuffer->resetAttachment(this, attachment);
Jamie Madillc29968b2016-01-20 11:17:23 -05003022 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003023
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003024 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003025}
3026
3027void Context::drawBuffers(GLsizei n, const GLenum *bufs)
3028{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003029 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003030 ASSERT(framebuffer);
3031 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003032 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003033}
3034
3035void Context::readBuffer(GLenum mode)
3036{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003037 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05003038 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003039 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05003040}
3041
3042void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
3043{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003044 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003045 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003046
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003047 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003048 ASSERT(framebuffer);
3049
3050 // The specification isn't clear what should be done when the framebuffer isn't complete.
3051 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04003052 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003053}
3054
3055void Context::invalidateFramebuffer(GLenum target,
3056 GLsizei numAttachments,
3057 const GLenum *attachments)
3058{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003059 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003060 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003061
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003062 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003063 ASSERT(framebuffer);
3064
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003065 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003066 {
Jamie Madill437fa652016-05-03 15:13:24 -04003067 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003068 }
Jamie Madill437fa652016-05-03 15:13:24 -04003069
3070 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05003071}
3072
3073void Context::invalidateSubFramebuffer(GLenum target,
3074 GLsizei numAttachments,
3075 const GLenum *attachments,
3076 GLint x,
3077 GLint y,
3078 GLsizei width,
3079 GLsizei height)
3080{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003081 // Only sync the FBO
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003082 mGLState.syncDirtyObject(this, target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05003083
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003084 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05003085 ASSERT(framebuffer);
3086
Jamie Madilldd43e6c2017-03-24 14:18:49 -04003087 if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05003088 {
Jamie Madill437fa652016-05-03 15:13:24 -04003089 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05003090 }
Jamie Madill437fa652016-05-03 15:13:24 -04003091
3092 Rectangle area(x, y, width, height);
3093 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05003094}
3095
Jamie Madill73a84962016-02-12 09:27:23 -05003096void Context::texImage2D(GLenum target,
3097 GLint level,
3098 GLint internalformat,
3099 GLsizei width,
3100 GLsizei height,
3101 GLint border,
3102 GLenum format,
3103 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003104 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003105{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003106 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003107
3108 Extents size(width, height, 1);
3109 Texture *texture =
3110 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003111 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3112 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003113}
3114
3115void Context::texImage3D(GLenum target,
3116 GLint level,
3117 GLint internalformat,
3118 GLsizei width,
3119 GLsizei height,
3120 GLsizei depth,
3121 GLint border,
3122 GLenum format,
3123 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003124 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003125{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003126 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003127
3128 Extents size(width, height, depth);
3129 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003130 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
3131 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003132}
3133
3134void Context::texSubImage2D(GLenum target,
3135 GLint level,
3136 GLint xoffset,
3137 GLint yoffset,
3138 GLsizei width,
3139 GLsizei height,
3140 GLenum format,
3141 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003142 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003143{
3144 // Zero sized uploads are valid but no-ops
3145 if (width == 0 || height == 0)
3146 {
3147 return;
3148 }
3149
Jamie Madillad9f24e2016-02-12 09:27:24 -05003150 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003151
3152 Box area(xoffset, yoffset, 0, width, height, 1);
3153 Texture *texture =
3154 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003155 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3156 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003157}
3158
3159void Context::texSubImage3D(GLenum target,
3160 GLint level,
3161 GLint xoffset,
3162 GLint yoffset,
3163 GLint zoffset,
3164 GLsizei width,
3165 GLsizei height,
3166 GLsizei depth,
3167 GLenum format,
3168 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003169 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05003170{
3171 // Zero sized uploads are valid but no-ops
3172 if (width == 0 || height == 0 || depth == 0)
3173 {
3174 return;
3175 }
3176
Jamie Madillad9f24e2016-02-12 09:27:24 -05003177 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003178
3179 Box area(xoffset, yoffset, zoffset, width, height, depth);
3180 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003181 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
3182 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05003183}
3184
3185void Context::compressedTexImage2D(GLenum target,
3186 GLint level,
3187 GLenum internalformat,
3188 GLsizei width,
3189 GLsizei height,
3190 GLint border,
3191 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003192 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003193{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003194 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003195
3196 Extents size(width, height, 1);
3197 Texture *texture =
3198 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003199 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003201 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003202}
3203
3204void Context::compressedTexImage3D(GLenum target,
3205 GLint level,
3206 GLenum internalformat,
3207 GLsizei width,
3208 GLsizei height,
3209 GLsizei depth,
3210 GLint border,
3211 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003212 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003213{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003214 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003215
3216 Extents size(width, height, depth);
3217 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003218 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04003220 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003221}
3222
3223void Context::compressedTexSubImage2D(GLenum target,
3224 GLint level,
3225 GLint xoffset,
3226 GLint yoffset,
3227 GLsizei width,
3228 GLsizei height,
3229 GLenum format,
3230 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003231 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003232{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003233 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003234
3235 Box area(xoffset, yoffset, 0, width, height, 1);
3236 Texture *texture =
3237 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003238 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 format, imageSize,
3240 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003241}
3242
3243void Context::compressedTexSubImage3D(GLenum target,
3244 GLint level,
3245 GLint xoffset,
3246 GLint yoffset,
3247 GLint zoffset,
3248 GLsizei width,
3249 GLsizei height,
3250 GLsizei depth,
3251 GLenum format,
3252 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04003253 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05003254{
3255 // Zero sized uploads are valid but no-ops
3256 if (width == 0 || height == 0)
3257 {
3258 return;
3259 }
3260
Jamie Madillad9f24e2016-02-12 09:27:24 -05003261 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003262
3263 Box area(xoffset, yoffset, zoffset, width, height, depth);
3264 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003265 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 format, imageSize,
3267 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003268}
3269
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003270void Context::generateMipmap(GLenum target)
3271{
3272 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003273 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003274}
3275
Geoff Lang97073d12016-04-20 10:42:34 -07003276void Context::copyTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003277 GLint sourceLevel,
3278 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003279 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003280 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003281 GLint internalFormat,
3282 GLenum destType,
3283 GLboolean unpackFlipY,
3284 GLboolean unpackPremultiplyAlpha,
3285 GLboolean unpackUnmultiplyAlpha)
3286{
3287 syncStateForTexImage();
3288
3289 gl::Texture *sourceTexture = getTexture(sourceId);
3290 gl::Texture *destTexture = getTexture(destId);
Geoff Langfc72a072017-03-24 14:52:39 -04003291 handleError(destTexture->copyTexture(
3292 this, destTarget, destLevel, internalFormat, destType, sourceLevel, unpackFlipY == GL_TRUE,
3293 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003294}
3295
3296void Context::copySubTextureCHROMIUM(GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003297 GLint sourceLevel,
3298 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003299 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003300 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003301 GLint xoffset,
3302 GLint yoffset,
3303 GLint x,
3304 GLint y,
3305 GLsizei width,
3306 GLsizei height,
3307 GLboolean unpackFlipY,
3308 GLboolean unpackPremultiplyAlpha,
3309 GLboolean unpackUnmultiplyAlpha)
3310{
3311 // Zero sized copies are valid but no-ops
3312 if (width == 0 || height == 0)
3313 {
3314 return;
3315 }
3316
3317 syncStateForTexImage();
3318
3319 gl::Texture *sourceTexture = getTexture(sourceId);
3320 gl::Texture *destTexture = getTexture(destId);
3321 Offset offset(xoffset, yoffset, 0);
3322 Rectangle area(x, y, width, height);
Geoff Langfc72a072017-03-24 14:52:39 -04003323 handleError(destTexture->copySubTexture(
3324 this, destTarget, destLevel, offset, sourceLevel, area, unpackFlipY == GL_TRUE,
3325 unpackPremultiplyAlpha == GL_TRUE, unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
Geoff Lang97073d12016-04-20 10:42:34 -07003326}
3327
Geoff Lang47110bf2016-04-20 11:13:22 -07003328void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3329{
3330 syncStateForTexImage();
3331
3332 gl::Texture *sourceTexture = getTexture(sourceId);
3333 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003334 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003335}
3336
Geoff Lang496c02d2016-10-20 11:38:11 -07003337void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003340 ASSERT(buffer);
3341
Geoff Lang496c02d2016-10-20 11:38:11 -07003342 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003343}
3344
Jamie Madill876429b2017-04-20 15:46:24 -04003345void *Context::mapBuffer(GLenum target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003346{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003347 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003348 ASSERT(buffer);
3349
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003350 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003351 if (error.isError())
3352 {
Jamie Madill437fa652016-05-03 15:13:24 -04003353 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003354 return nullptr;
3355 }
3356
3357 return buffer->getMapPointer();
3358}
3359
3360GLboolean Context::unmapBuffer(GLenum target)
3361{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003362 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003363 ASSERT(buffer);
3364
3365 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003366 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003367 if (error.isError())
3368 {
Jamie Madill437fa652016-05-03 15:13:24 -04003369 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003370 return GL_FALSE;
3371 }
3372
3373 return result;
3374}
3375
Jamie Madill876429b2017-04-20 15:46:24 -04003376void *Context::mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003378 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003379 ASSERT(buffer);
3380
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003381 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003382 if (error.isError())
3383 {
Jamie Madill437fa652016-05-03 15:13:24 -04003384 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003385 return nullptr;
3386 }
3387
3388 return buffer->getMapPointer();
3389}
3390
3391void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3392{
3393 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3394}
3395
Jamie Madillad9f24e2016-02-12 09:27:24 -05003396void Context::syncStateForReadPixels()
3397{
3398 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3399}
3400
3401void Context::syncStateForTexImage()
3402{
3403 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3404}
3405
3406void Context::syncStateForClear()
3407{
3408 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3409}
3410
3411void Context::syncStateForBlit()
3412{
3413 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3414}
3415
Jamie Madillc20ab272016-06-09 07:20:46 -07003416void Context::activeTexture(GLenum texture)
3417{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419}
3420
Jamie Madill876429b2017-04-20 15:46:24 -04003421void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003422{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003424}
3425
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003426void Context::blendEquation(GLenum mode)
3427{
3428 mGLState.setBlendEquation(mode, mode);
3429}
3430
Jamie Madillc20ab272016-06-09 07:20:46 -07003431void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3432{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003433 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003434}
3435
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003436void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3437{
3438 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3439}
3440
Jamie Madillc20ab272016-06-09 07:20:46 -07003441void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3442{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003443 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003444}
3445
Jamie Madill876429b2017-04-20 15:46:24 -04003446void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc20ab272016-06-09 07:20:46 -07003447{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449}
3450
Jamie Madill876429b2017-04-20 15:46:24 -04003451void Context::clearDepthf(GLfloat depth)
Jamie Madillc20ab272016-06-09 07:20:46 -07003452{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003453 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003454}
3455
3456void Context::clearStencil(GLint s)
3457{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003458 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003459}
3460
3461void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3462{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003464}
3465
3466void Context::cullFace(GLenum mode)
3467{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
3471void Context::depthFunc(GLenum func)
3472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474}
3475
3476void Context::depthMask(GLboolean flag)
3477{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479}
3480
Jamie Madill876429b2017-04-20 15:46:24 -04003481void Context::depthRangef(GLfloat zNear, GLfloat zFar)
Jamie Madillc20ab272016-06-09 07:20:46 -07003482{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::disable(GLenum cap)
3487{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
3491void Context::disableVertexAttribArray(GLuint index)
3492{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003493 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003494}
3495
3496void Context::enable(GLenum cap)
3497{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003498 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003499}
3500
3501void Context::enableVertexAttribArray(GLuint index)
3502{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504}
3505
3506void Context::frontFace(GLenum mode)
3507{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::hint(GLenum target, GLenum mode)
3512{
3513 switch (target)
3514 {
3515 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003517 break;
3518
3519 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003520 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003521 break;
3522
3523 default:
3524 UNREACHABLE();
3525 return;
3526 }
3527}
3528
3529void Context::lineWidth(GLfloat width)
3530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003531 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003532}
3533
3534void Context::pixelStorei(GLenum pname, GLint param)
3535{
3536 switch (pname)
3537 {
3538 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003539 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003540 break;
3541
3542 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003543 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003544 break;
3545
3546 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003547 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003548 break;
3549
3550 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003551 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003552 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003553 break;
3554
3555 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003556 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003557 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003558 break;
3559
3560 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003561 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003562 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003563 break;
3564
3565 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003566 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003567 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003568 break;
3569
3570 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003571 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003572 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003573 break;
3574
3575 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003576 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003577 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003578 break;
3579
3580 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003581 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003582 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003583 break;
3584
3585 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003586 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003587 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003588 break;
3589
3590 default:
3591 UNREACHABLE();
3592 return;
3593 }
3594}
3595
3596void Context::polygonOffset(GLfloat factor, GLfloat units)
3597{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003598 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003599}
3600
Jamie Madill876429b2017-04-20 15:46:24 -04003601void Context::sampleCoverage(GLfloat value, GLboolean invert)
Jamie Madillc20ab272016-06-09 07:20:46 -07003602{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003603 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003604}
3605
3606void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3607{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003608 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003609}
3610
3611void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3612{
3613 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3614 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003615 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003616 }
3617
3618 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3619 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003620 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003621 }
3622}
3623
3624void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3625{
3626 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3627 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003628 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003629 }
3630
3631 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3632 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003633 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003634 }
3635}
3636
3637void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3638{
3639 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3640 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003641 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003642 }
3643
3644 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3645 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003646 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003647 }
3648}
3649
3650void Context::vertexAttrib1f(GLuint index, GLfloat x)
3651{
3652 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003653 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003654}
3655
3656void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3657{
3658 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003659 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003660}
3661
3662void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3663{
3664 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003665 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003666}
3667
3668void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3669{
3670 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003671 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003672}
3673
3674void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3675{
3676 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003677 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003678}
3679
3680void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3681{
3682 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003683 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003684}
3685
3686void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3687{
3688 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003689 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003690}
3691
3692void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3693{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003694 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003695}
3696
3697void Context::vertexAttribPointer(GLuint index,
3698 GLint size,
3699 GLenum type,
3700 GLboolean normalized,
3701 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003702 const void *ptr)
Jamie Madillc20ab272016-06-09 07:20:46 -07003703{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003704 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3705 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003706}
3707
Shao80957d92017-02-20 21:25:59 +08003708void Context::vertexAttribFormat(GLuint attribIndex,
3709 GLint size,
3710 GLenum type,
3711 GLboolean normalized,
3712 GLuint relativeOffset)
3713{
3714 mGLState.setVertexAttribFormat(attribIndex, size, type, normalized == GL_TRUE, false,
3715 relativeOffset);
3716}
3717
3718void Context::vertexAttribIFormat(GLuint attribIndex,
3719 GLint size,
3720 GLenum type,
3721 GLuint relativeOffset)
3722{
3723 mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
3724}
3725
3726void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
3727{
3728 mGLState.setVertexAttribBinding(attribIndex, bindingIndex);
3729}
3730
3731void Context::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
3732{
3733 mGLState.setVertexBindingDivisor(bindingIndex, divisor);
3734}
3735
Jamie Madillc20ab272016-06-09 07:20:46 -07003736void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3737{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003738 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003739}
3740
3741void Context::vertexAttribIPointer(GLuint index,
3742 GLint size,
3743 GLenum type,
3744 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04003745 const void *pointer)
Jamie Madillc20ab272016-06-09 07:20:46 -07003746{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003747 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3748 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003749}
3750
3751void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3752{
3753 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003754 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003755}
3756
3757void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3758{
3759 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003760 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003761}
3762
3763void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3764{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003765 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003766}
3767
3768void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3769{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003770 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003771}
3772
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003773void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
3774{
3775 const VertexAttribCurrentValueData &currentValues =
3776 getGLState().getVertexAttribCurrentValue(index);
3777 const VertexArray *vao = getGLState().getVertexArray();
3778 QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3779 currentValues, pname, params);
3780}
3781
3782void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
3783{
3784 const VertexAttribCurrentValueData &currentValues =
3785 getGLState().getVertexAttribCurrentValue(index);
3786 const VertexArray *vao = getGLState().getVertexArray();
3787 QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3788 currentValues, pname, params);
3789}
3790
3791void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
3792{
3793 const VertexAttribCurrentValueData &currentValues =
3794 getGLState().getVertexAttribCurrentValue(index);
3795 const VertexArray *vao = getGLState().getVertexArray();
3796 QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3797 currentValues, pname, params);
3798}
3799
3800void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
3801{
3802 const VertexAttribCurrentValueData &currentValues =
3803 getGLState().getVertexAttribCurrentValue(index);
3804 const VertexArray *vao = getGLState().getVertexArray();
3805 QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
3806 currentValues, pname, params);
3807}
3808
Jamie Madill876429b2017-04-20 15:46:24 -04003809void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
Jiawei-Shao2597fb62016-12-09 16:38:02 +08003810{
3811 const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index);
3812 QueryVertexAttribPointerv(attrib, pname, pointer);
3813}
3814
Jamie Madillc20ab272016-06-09 07:20:46 -07003815void Context::debugMessageControl(GLenum source,
3816 GLenum type,
3817 GLenum severity,
3818 GLsizei count,
3819 const GLuint *ids,
3820 GLboolean enabled)
3821{
3822 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003823 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3824 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003825}
3826
3827void Context::debugMessageInsert(GLenum source,
3828 GLenum type,
3829 GLuint id,
3830 GLenum severity,
3831 GLsizei length,
3832 const GLchar *buf)
3833{
3834 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003835 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003836}
3837
3838void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3839{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003840 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003841}
3842
3843GLuint Context::getDebugMessageLog(GLuint count,
3844 GLsizei bufSize,
3845 GLenum *sources,
3846 GLenum *types,
3847 GLuint *ids,
3848 GLenum *severities,
3849 GLsizei *lengths,
3850 GLchar *messageLog)
3851{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003852 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3853 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003854}
3855
3856void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3857{
3858 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003859 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003860}
3861
3862void Context::popDebugGroup()
3863{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003864 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003865}
3866
Jamie Madill876429b2017-04-20 15:46:24 -04003867void Context::bufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Jamie Madill29639852016-09-02 15:00:09 -04003868{
3869 Buffer *buffer = mGLState.getTargetBuffer(target);
3870 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003871 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003872}
3873
Jamie Madill876429b2017-04-20 15:46:24 -04003874void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04003875{
3876 if (data == nullptr)
3877 {
3878 return;
3879 }
3880
3881 Buffer *buffer = mGLState.getTargetBuffer(target);
3882 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003883 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003884}
3885
Jamie Madillef300b12016-10-07 15:12:09 -04003886void Context::attachShader(GLuint program, GLuint shader)
3887{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003888 auto programObject = mState.mShaderPrograms->getProgram(program);
3889 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003890 ASSERT(programObject && shaderObject);
3891 programObject->attachShader(shaderObject);
3892}
3893
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003894const Workarounds &Context::getWorkarounds() const
3895{
3896 return mWorkarounds;
3897}
3898
Jamie Madillb0817d12016-11-01 15:48:31 -04003899void Context::copyBufferSubData(GLenum readTarget,
3900 GLenum writeTarget,
3901 GLintptr readOffset,
3902 GLintptr writeOffset,
3903 GLsizeiptr size)
3904{
3905 // if size is zero, the copy is a successful no-op
3906 if (size == 0)
3907 {
3908 return;
3909 }
3910
3911 // TODO(jmadill): cache these.
3912 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3913 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3914
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003915 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003916}
3917
Jamie Madill01a80ee2016-11-07 12:06:18 -05003918void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3919{
3920 Program *programObject = getProgram(program);
3921 // TODO(jmadill): Re-use this from the validation if possible.
3922 ASSERT(programObject);
3923 programObject->bindAttributeLocation(index, name);
3924}
3925
3926void Context::bindBuffer(GLenum target, GLuint buffer)
3927{
3928 switch (target)
3929 {
3930 case GL_ARRAY_BUFFER:
3931 bindArrayBuffer(buffer);
3932 break;
3933 case GL_ELEMENT_ARRAY_BUFFER:
3934 bindElementArrayBuffer(buffer);
3935 break;
3936 case GL_COPY_READ_BUFFER:
3937 bindCopyReadBuffer(buffer);
3938 break;
3939 case GL_COPY_WRITE_BUFFER:
3940 bindCopyWriteBuffer(buffer);
3941 break;
3942 case GL_PIXEL_PACK_BUFFER:
3943 bindPixelPackBuffer(buffer);
3944 break;
3945 case GL_PIXEL_UNPACK_BUFFER:
3946 bindPixelUnpackBuffer(buffer);
3947 break;
3948 case GL_UNIFORM_BUFFER:
3949 bindGenericUniformBuffer(buffer);
3950 break;
3951 case GL_TRANSFORM_FEEDBACK_BUFFER:
3952 bindGenericTransformFeedbackBuffer(buffer);
3953 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003954 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08003955 bindGenericAtomicCounterBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003956 break;
3957 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08003958 bindGenericShaderStorageBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003959 break;
3960 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003961 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003962 break;
3963 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003964 if (buffer != 0)
3965 {
3966 // Binding buffers to this binding point is not implemented yet.
3967 UNIMPLEMENTED();
3968 }
Geoff Lang3b573612016-10-31 14:08:10 -04003969 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003970
3971 default:
3972 UNREACHABLE();
3973 break;
3974 }
3975}
3976
Jiajia Qin6eafb042016-12-27 17:04:07 +08003977void Context::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
3978{
3979 bindBufferRange(target, index, buffer, 0, 0);
3980}
3981
3982void Context::bindBufferRange(GLenum target,
3983 GLuint index,
3984 GLuint buffer,
3985 GLintptr offset,
3986 GLsizeiptr size)
3987{
3988 switch (target)
3989 {
3990 case GL_TRANSFORM_FEEDBACK_BUFFER:
3991 bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
3992 bindGenericTransformFeedbackBuffer(buffer);
3993 break;
3994 case GL_UNIFORM_BUFFER:
3995 bindIndexedUniformBuffer(buffer, index, offset, size);
3996 bindGenericUniformBuffer(buffer);
3997 break;
3998 case GL_ATOMIC_COUNTER_BUFFER:
3999 bindIndexedAtomicCounterBuffer(buffer, index, offset, size);
4000 bindGenericAtomicCounterBuffer(buffer);
4001 break;
4002 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08004003 bindIndexedShaderStorageBuffer(buffer, index, offset, size);
4004 bindGenericShaderStorageBuffer(buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08004005 break;
4006 default:
4007 UNREACHABLE();
4008 break;
4009 }
4010}
4011
Jamie Madill01a80ee2016-11-07 12:06:18 -05004012void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
4013{
4014 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4015 {
4016 bindReadFramebuffer(framebuffer);
4017 }
4018
4019 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
4020 {
4021 bindDrawFramebuffer(framebuffer);
4022 }
4023}
4024
4025void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
4026{
4027 ASSERT(target == GL_RENDERBUFFER);
4028 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05004029 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004030 mGLState.setRenderbufferBinding(object);
4031}
4032
JiangYizhoubddc46b2016-12-09 09:50:51 +08004033void Context::texStorage2DMultisample(GLenum target,
4034 GLsizei samples,
4035 GLenum internalformat,
4036 GLsizei width,
4037 GLsizei height,
4038 GLboolean fixedsamplelocations)
4039{
4040 Extents size(width, height, 1);
4041 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05004042 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08004043 fixedsamplelocations));
4044}
4045
4046void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
4047{
Jamie Madilldd43e6c2017-03-24 14:18:49 -04004048 mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER);
JiangYizhoubddc46b2016-12-09 09:50:51 +08004049 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
4050
4051 switch (pname)
4052 {
4053 case GL_SAMPLE_POSITION:
4054 handleError(framebuffer->getSamplePosition(index, val));
4055 break;
4056 default:
4057 UNREACHABLE();
4058 }
4059}
4060
Jamie Madille8fb6402017-02-14 17:56:40 -05004061void Context::renderbufferStorage(GLenum target,
4062 GLenum internalformat,
4063 GLsizei width,
4064 GLsizei height)
4065{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004066 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4067 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
4068
Jamie Madille8fb6402017-02-14 17:56:40 -05004069 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004070 handleError(renderbuffer->setStorage(convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004071}
4072
4073void Context::renderbufferStorageMultisample(GLenum target,
4074 GLsizei samples,
4075 GLenum internalformat,
4076 GLsizei width,
4077 GLsizei height)
4078{
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004079 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
4080 GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
Jamie Madille8fb6402017-02-14 17:56:40 -05004081
4082 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
Jamie Madill4e0e6f82017-02-17 11:06:03 -05004083 handleError(
4084 renderbuffer->setStorageMultisample(samples, convertedInternalFormat, width, height));
Jamie Madille8fb6402017-02-14 17:56:40 -05004085}
4086
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004087void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
4088{
4089 const FenceSync *syncObject = getFenceSync(sync);
Geoff Lang82483b92017-04-11 15:33:00 -04004090 handleError(QuerySynciv(syncObject, pname, bufSize, length, values));
Geoff Lang38f2cfb2017-04-11 15:23:08 -04004091}
4092
JiangYizhoue18e6392017-02-20 10:32:23 +08004093void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
4094{
4095 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4096 QueryFramebufferParameteriv(framebuffer, pname, params);
4097}
4098
4099void Context::setFramebufferParameteri(GLenum target, GLenum pname, GLint param)
4100{
4101 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4102 SetFramebufferParameteri(framebuffer, pname, param);
4103}
4104
Jamie Madille14951e2017-03-09 18:55:16 -05004105Error Context::getScratchBuffer(size_t requestedSize, angle::MemoryBuffer **scratchBufferOut) const
4106{
4107 if (!mScratchBuffer.get(requestedSize, scratchBufferOut))
4108 {
4109 return gl::OutOfMemory() << "Failed to allocate internal buffer.";
4110 }
4111 return gl::NoError();
4112}
4113
Xinghua Cao2b396592017-03-29 15:36:04 +08004114void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
4115{
4116 if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
4117 {
4118 return;
4119 }
4120
4121 mImplementation->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
4122}
4123
Jamie Madillc1d770e2017-04-13 17:31:24 -04004124GLenum Context::checkFramebufferStatus(GLenum target)
4125{
4126 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
4127 ASSERT(framebuffer);
4128
4129 return framebuffer->checkStatus(this);
4130}
4131
4132void Context::compileShader(GLuint shader)
4133{
4134 Shader *shaderObject = GetValidShader(this, shader);
4135 if (!shaderObject)
4136 {
4137 return;
4138 }
4139 shaderObject->compile(this);
4140}
4141
4142void Context::deleteBuffers(GLsizei n, const GLuint *buffers)
4143{
4144 for (int i = 0; i < n; i++)
4145 {
4146 deleteBuffer(buffers[i]);
4147 }
4148}
4149
4150void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers)
4151{
4152 for (int i = 0; i < n; i++)
4153 {
4154 if (framebuffers[i] != 0)
4155 {
4156 deleteFramebuffer(framebuffers[i]);
4157 }
4158 }
4159}
4160
4161void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
4162{
4163 for (int i = 0; i < n; i++)
4164 {
4165 deleteRenderbuffer(renderbuffers[i]);
4166 }
4167}
4168
4169void Context::deleteTextures(GLsizei n, const GLuint *textures)
4170{
4171 for (int i = 0; i < n; i++)
4172 {
4173 if (textures[i] != 0)
4174 {
4175 deleteTexture(textures[i]);
4176 }
4177 }
4178}
4179
4180void Context::detachShader(GLuint program, GLuint shader)
4181{
4182 Program *programObject = getProgram(program);
4183 ASSERT(programObject);
4184
4185 Shader *shaderObject = getShader(shader);
4186 ASSERT(shaderObject);
4187
4188 programObject->detachShader(this, shaderObject);
4189}
4190
4191void Context::genBuffers(GLsizei n, GLuint *buffers)
4192{
4193 for (int i = 0; i < n; i++)
4194 {
4195 buffers[i] = createBuffer();
4196 }
4197}
4198
4199void Context::genFramebuffers(GLsizei n, GLuint *framebuffers)
4200{
4201 for (int i = 0; i < n; i++)
4202 {
4203 framebuffers[i] = createFramebuffer();
4204 }
4205}
4206
4207void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers)
4208{
4209 for (int i = 0; i < n; i++)
4210 {
4211 renderbuffers[i] = createRenderbuffer();
4212 }
4213}
4214
4215void Context::genTextures(GLsizei n, GLuint *textures)
4216{
4217 for (int i = 0; i < n; i++)
4218 {
4219 textures[i] = createTexture();
4220 }
4221}
4222
4223void Context::getActiveAttrib(GLuint program,
4224 GLuint index,
4225 GLsizei bufsize,
4226 GLsizei *length,
4227 GLint *size,
4228 GLenum *type,
4229 GLchar *name)
4230{
4231 Program *programObject = getProgram(program);
4232 ASSERT(programObject);
4233 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
4234}
4235
4236void Context::getActiveUniform(GLuint program,
4237 GLuint index,
4238 GLsizei bufsize,
4239 GLsizei *length,
4240 GLint *size,
4241 GLenum *type,
4242 GLchar *name)
4243{
4244 Program *programObject = getProgram(program);
4245 ASSERT(programObject);
4246 programObject->getActiveUniform(index, bufsize, length, size, type, name);
4247}
4248
4249void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
4250{
4251 Program *programObject = getProgram(program);
4252 ASSERT(programObject);
4253 programObject->getAttachedShaders(maxcount, count, shaders);
4254}
4255
4256GLint Context::getAttribLocation(GLuint program, const GLchar *name)
4257{
4258 Program *programObject = getProgram(program);
4259 ASSERT(programObject);
4260 return programObject->getAttributeLocation(name);
4261}
4262
4263void Context::getBooleanv(GLenum pname, GLboolean *params)
4264{
4265 GLenum nativeType;
4266 unsigned int numParams = 0;
4267 getQueryParameterInfo(pname, &nativeType, &numParams);
4268
4269 if (nativeType == GL_BOOL)
4270 {
4271 getBooleanvImpl(pname, params);
4272 }
4273 else
4274 {
4275 CastStateValues(this, nativeType, pname, numParams, params);
4276 }
4277}
4278
4279void Context::getFloatv(GLenum pname, GLfloat *params)
4280{
4281 GLenum nativeType;
4282 unsigned int numParams = 0;
4283 getQueryParameterInfo(pname, &nativeType, &numParams);
4284
4285 if (nativeType == GL_FLOAT)
4286 {
4287 getFloatvImpl(pname, params);
4288 }
4289 else
4290 {
4291 CastStateValues(this, nativeType, pname, numParams, params);
4292 }
4293}
4294
4295void Context::getIntegerv(GLenum pname, GLint *params)
4296{
4297 GLenum nativeType;
4298 unsigned int numParams = 0;
4299 getQueryParameterInfo(pname, &nativeType, &numParams);
4300
4301 if (nativeType == GL_INT)
4302 {
4303 getIntegervImpl(pname, params);
4304 }
4305 else
4306 {
4307 CastStateValues(this, nativeType, pname, numParams, params);
4308 }
4309}
4310
4311void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
4312{
4313 Program *programObject = getProgram(program);
4314 ASSERT(programObject);
4315 QueryProgramiv(programObject, pname, params);
4316}
4317
Jamie Madillbe849e42017-05-02 15:49:00 -04004318void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004319{
4320 Program *programObject = getProgram(program);
4321 ASSERT(programObject);
4322 programObject->getInfoLog(bufsize, length, infolog);
4323}
4324
4325void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params)
4326{
4327 Shader *shaderObject = getShader(shader);
4328 ASSERT(shaderObject);
4329 QueryShaderiv(shaderObject, pname, params);
4330}
4331
4332void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog)
4333{
4334 Shader *shaderObject = getShader(shader);
4335 ASSERT(shaderObject);
4336 shaderObject->getInfoLog(bufsize, length, infolog);
4337}
4338
4339void Context::getShaderPrecisionFormat(GLenum shadertype,
4340 GLenum precisiontype,
4341 GLint *range,
4342 GLint *precision)
4343{
4344 // TODO(jmadill): Compute shaders.
4345
4346 switch (shadertype)
4347 {
4348 case GL_VERTEX_SHADER:
4349 switch (precisiontype)
4350 {
4351 case GL_LOW_FLOAT:
4352 mCaps.vertexLowpFloat.get(range, precision);
4353 break;
4354 case GL_MEDIUM_FLOAT:
4355 mCaps.vertexMediumpFloat.get(range, precision);
4356 break;
4357 case GL_HIGH_FLOAT:
4358 mCaps.vertexHighpFloat.get(range, precision);
4359 break;
4360
4361 case GL_LOW_INT:
4362 mCaps.vertexLowpInt.get(range, precision);
4363 break;
4364 case GL_MEDIUM_INT:
4365 mCaps.vertexMediumpInt.get(range, precision);
4366 break;
4367 case GL_HIGH_INT:
4368 mCaps.vertexHighpInt.get(range, precision);
4369 break;
4370
4371 default:
4372 UNREACHABLE();
4373 return;
4374 }
4375 break;
4376
4377 case GL_FRAGMENT_SHADER:
4378 switch (precisiontype)
4379 {
4380 case GL_LOW_FLOAT:
4381 mCaps.fragmentLowpFloat.get(range, precision);
4382 break;
4383 case GL_MEDIUM_FLOAT:
4384 mCaps.fragmentMediumpFloat.get(range, precision);
4385 break;
4386 case GL_HIGH_FLOAT:
4387 mCaps.fragmentHighpFloat.get(range, precision);
4388 break;
4389
4390 case GL_LOW_INT:
4391 mCaps.fragmentLowpInt.get(range, precision);
4392 break;
4393 case GL_MEDIUM_INT:
4394 mCaps.fragmentMediumpInt.get(range, precision);
4395 break;
4396 case GL_HIGH_INT:
4397 mCaps.fragmentHighpInt.get(range, precision);
4398 break;
4399
4400 default:
4401 UNREACHABLE();
4402 return;
4403 }
4404 break;
4405
4406 default:
4407 UNREACHABLE();
4408 return;
4409 }
4410}
4411
4412void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
4413{
4414 Shader *shaderObject = getShader(shader);
4415 ASSERT(shaderObject);
4416 shaderObject->getSource(bufsize, length, source);
4417}
4418
4419void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
4420{
4421 Program *programObject = getProgram(program);
4422 ASSERT(programObject);
4423 programObject->getUniformfv(location, params);
4424}
4425
4426void Context::getUniformiv(GLuint program, GLint location, GLint *params)
4427{
4428 Program *programObject = getProgram(program);
4429 ASSERT(programObject);
4430 programObject->getUniformiv(location, params);
4431}
4432
4433GLint Context::getUniformLocation(GLuint program, const GLchar *name)
4434{
4435 Program *programObject = getProgram(program);
4436 ASSERT(programObject);
4437 return programObject->getUniformLocation(name);
4438}
4439
4440GLboolean Context::isBuffer(GLuint buffer)
4441{
4442 if (buffer == 0)
4443 {
4444 return GL_FALSE;
4445 }
4446
4447 return (getBuffer(buffer) ? GL_TRUE : GL_FALSE);
4448}
4449
4450GLboolean Context::isEnabled(GLenum cap)
4451{
4452 return mGLState.getEnableFeature(cap);
4453}
4454
4455GLboolean Context::isFramebuffer(GLuint framebuffer)
4456{
4457 if (framebuffer == 0)
4458 {
4459 return GL_FALSE;
4460 }
4461
4462 return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE);
4463}
4464
4465GLboolean Context::isProgram(GLuint program)
4466{
4467 if (program == 0)
4468 {
4469 return GL_FALSE;
4470 }
4471
4472 return (getProgram(program) ? GL_TRUE : GL_FALSE);
4473}
4474
4475GLboolean Context::isRenderbuffer(GLuint renderbuffer)
4476{
4477 if (renderbuffer == 0)
4478 {
4479 return GL_FALSE;
4480 }
4481
4482 return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE);
4483}
4484
4485GLboolean Context::isShader(GLuint shader)
4486{
4487 if (shader == 0)
4488 {
4489 return GL_FALSE;
4490 }
4491
4492 return (getShader(shader) ? GL_TRUE : GL_FALSE);
4493}
4494
4495GLboolean Context::isTexture(GLuint texture)
4496{
4497 if (texture == 0)
4498 {
4499 return GL_FALSE;
4500 }
4501
4502 return (getTexture(texture) ? GL_TRUE : GL_FALSE);
4503}
4504
4505void Context::linkProgram(GLuint program)
4506{
4507 Program *programObject = getProgram(program);
4508 ASSERT(programObject);
4509 handleError(programObject->link(this));
4510}
4511
4512void Context::releaseShaderCompiler()
4513{
4514 handleError(mCompiler->release());
4515}
4516
4517void Context::shaderBinary(GLsizei n,
4518 const GLuint *shaders,
4519 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04004520 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004521 GLsizei length)
4522{
4523 // No binary shader formats are supported.
4524 UNIMPLEMENTED();
4525}
4526
4527void Context::shaderSource(GLuint shader,
4528 GLsizei count,
4529 const GLchar *const *string,
4530 const GLint *length)
4531{
4532 Shader *shaderObject = getShader(shader);
4533 ASSERT(shaderObject);
4534 shaderObject->setSource(count, string, length);
4535}
4536
4537void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
4538{
4539 stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4540}
4541
4542void Context::stencilMask(GLuint mask)
4543{
4544 stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4545}
4546
4547void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4548{
4549 stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4550}
4551
4552void Context::uniform1f(GLint location, GLfloat x)
4553{
4554 Program *program = mGLState.getProgram();
4555 program->setUniform1fv(location, 1, &x);
4556}
4557
4558void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
4559{
4560 Program *program = mGLState.getProgram();
4561 program->setUniform1fv(location, count, v);
4562}
4563
4564void Context::uniform1i(GLint location, GLint x)
4565{
4566 Program *program = mGLState.getProgram();
4567 program->setUniform1iv(location, 1, &x);
4568}
4569
4570void Context::uniform1iv(GLint location, GLsizei count, const GLint *v)
4571{
4572 Program *program = mGLState.getProgram();
4573 program->setUniform1iv(location, count, v);
4574}
4575
4576void Context::uniform2f(GLint location, GLfloat x, GLfloat y)
4577{
4578 GLfloat xy[2] = {x, y};
4579 Program *program = mGLState.getProgram();
4580 program->setUniform2fv(location, 1, xy);
4581}
4582
4583void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v)
4584{
4585 Program *program = mGLState.getProgram();
4586 program->setUniform2fv(location, count, v);
4587}
4588
4589void Context::uniform2i(GLint location, GLint x, GLint y)
4590{
4591 GLint xy[2] = {x, y};
4592 Program *program = mGLState.getProgram();
4593 program->setUniform2iv(location, 1, xy);
4594}
4595
4596void Context::uniform2iv(GLint location, GLsizei count, const GLint *v)
4597{
4598 Program *program = mGLState.getProgram();
4599 program->setUniform2iv(location, count, v);
4600}
4601
4602void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4603{
4604 GLfloat xyz[3] = {x, y, z};
4605 Program *program = mGLState.getProgram();
4606 program->setUniform3fv(location, 1, xyz);
4607}
4608
4609void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v)
4610{
4611 Program *program = mGLState.getProgram();
4612 program->setUniform3fv(location, count, v);
4613}
4614
4615void Context::uniform3i(GLint location, GLint x, GLint y, GLint z)
4616{
4617 GLint xyz[3] = {x, y, z};
4618 Program *program = mGLState.getProgram();
4619 program->setUniform3iv(location, 1, xyz);
4620}
4621
4622void Context::uniform3iv(GLint location, GLsizei count, const GLint *v)
4623{
4624 Program *program = mGLState.getProgram();
4625 program->setUniform3iv(location, count, v);
4626}
4627
4628void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4629{
4630 GLfloat xyzw[4] = {x, y, z, w};
4631 Program *program = mGLState.getProgram();
4632 program->setUniform4fv(location, 1, xyzw);
4633}
4634
4635void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v)
4636{
4637 Program *program = mGLState.getProgram();
4638 program->setUniform4fv(location, count, v);
4639}
4640
4641void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4642{
4643 GLint xyzw[4] = {x, y, z, w};
4644 Program *program = mGLState.getProgram();
4645 program->setUniform4iv(location, 1, xyzw);
4646}
4647
4648void Context::uniform4iv(GLint location, GLsizei count, const GLint *v)
4649{
4650 Program *program = mGLState.getProgram();
4651 program->setUniform4iv(location, count, v);
4652}
4653
4654void Context::uniformMatrix2fv(GLint location,
4655 GLsizei count,
4656 GLboolean transpose,
4657 const GLfloat *value)
4658{
4659 Program *program = mGLState.getProgram();
4660 program->setUniformMatrix2fv(location, count, transpose, value);
4661}
4662
4663void Context::uniformMatrix3fv(GLint location,
4664 GLsizei count,
4665 GLboolean transpose,
4666 const GLfloat *value)
4667{
4668 Program *program = mGLState.getProgram();
4669 program->setUniformMatrix3fv(location, count, transpose, value);
4670}
4671
4672void Context::uniformMatrix4fv(GLint location,
4673 GLsizei count,
4674 GLboolean transpose,
4675 const GLfloat *value)
4676{
4677 Program *program = mGLState.getProgram();
4678 program->setUniformMatrix4fv(location, count, transpose, value);
4679}
4680
4681void Context::validateProgram(GLuint program)
4682{
4683 Program *programObject = getProgram(program);
4684 ASSERT(programObject);
4685 programObject->validate(mCaps);
4686}
4687
Jamie Madillc29968b2016-01-20 11:17:23 -05004688} // namespace gl