blob: d74f33057ae570f0eb5a5b9242edddfdcd7f3b2a [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 Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
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 Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.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"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.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>
Sami Väisänend59ca052016-06-21 16:10:00 +030048std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
49 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
68std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
69 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
Martin Radev9d901792016-07-15 15:58:58 +0300201std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
202{
203 std::string labelName;
204 if (label != nullptr)
205 {
206 size_t labelLength = length < 0 ? strlen(label) : length;
207 labelName = std::string(label, labelLength);
208 }
209 return labelName;
210}
211
212void GetObjectLabelBase(const std::string &objectLabel,
213 GLsizei bufSize,
214 GLsizei *length,
215 GLchar *label)
216{
217 size_t writeLength = objectLabel.length();
218 if (label != nullptr && bufSize > 0)
219 {
220 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
221 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
222 label[writeLength] = '\0';
223 }
224
225 if (length != nullptr)
226 {
227 *length = static_cast<GLsizei>(writeLength);
228 }
229}
230
Geoff Langf6db0982015-08-25 13:04:00 -0400231} // anonymous namespace
232
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233namespace gl
234{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000235
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400236Context::Context(rx::EGLImplFactory *implFactory,
237 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400238 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500239 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300240
Geoff Langeb66a6e2016-10-31 13:06:12 -0400241 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700242 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500243 mCaps,
244 mTextureCaps,
245 mExtensions,
246 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mLimitations,
Jamie Madill01a80ee2016-11-07 12:06:18 -0500248 mFramebufferMap,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500249 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700250 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500251 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400252 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500253 mClientType(EGL_OPENGL_ES_API),
254 mHasBeenCurrent(false),
255 mContextLost(false),
256 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700257 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mResetStrategy(GetResetStrategy(attribs)),
259 mRobustAccess(GetRobustAccess(attribs)),
260 mCurrentSurface(nullptr),
261 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000262{
Geoff Lang077f20a2016-11-01 10:08:02 -0400263 if (mRobustAccess)
264 {
265 UNIMPLEMENTED();
266 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000267
Geoff Langc287ea62016-09-16 14:46:51 -0400268 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700269 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400270
Geoff Langeb66a6e2016-10-31 13:06:12 -0400271 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400272 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100273
Shannon Woods53a94a82014-06-24 15:20:36 -0400274 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400275
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400276 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 {
278 mResourceManager = shareContext->mResourceManager;
279 mResourceManager->addRef();
280 }
281 else
282 {
Jamie Madill901b3792016-05-26 09:20:40 -0400283 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 }
285
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700286 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400287
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 // [OpenGL ES 2.0.24] section 3.7 page 83:
289 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
290 // and cube map texture state vectors respectively associated with them.
291 // In order that access to these initial textures not be lost, they are treated as texture
292 // objects all of whose names are 0.
293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500296
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400297 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500298 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
Geoff Langeb66a6e2016-10-31 13:06:12 -0400300 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 {
302 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400303 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500304 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400305
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400306 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000309
Ian Ewellbda75592016-04-18 17:25:54 -0400310 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
311 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400312 Texture *zeroTextureExternal =
313 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400314 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
315 }
316
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700317 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500318
Jamie Madill57a89722013-07-02 11:57:03 -0400319 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000320 bindArrayBuffer(0);
321 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400322
Jamie Madill01a80ee2016-11-07 12:06:18 -0500323 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000324
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000325 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400326 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000327 {
328 bindIndexedUniformBuffer(0, i, 0, -1);
329 }
330
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000331 bindCopyReadBuffer(0);
332 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000333 bindPixelPackBuffer(0);
334 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000335
Geoff Langeb66a6e2016-10-31 13:06:12 -0400336 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400337 {
338 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
339 // In the initial state, a default transform feedback object is bound and treated as
340 // a transform feedback object with a name of zero. That object is bound any time
341 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400342 bindTransformFeedback(0);
343 }
Geoff Langc8058452014-02-03 12:04:11 -0500344
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700345 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500346
347 // Initialize dirty bit masks
348 // TODO(jmadill): additional ES3 state
349 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
350 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
353 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
354 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400355 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500356 // No dirty objects.
357
358 // Readpixels uses the pack state and read FBO
359 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
360 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
361 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
362 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
363 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400364 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500365 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
366
367 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
368 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
369 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
370 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
371 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
372 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
373 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
374 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
375 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
376 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
377 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
378 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
379
380 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
381 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700382 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500383 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
384 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400385
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400386 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387}
388
389Context::~Context()
390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700391 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000392
Corentin Wallez37c39792015-08-20 14:19:46 -0400393 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400395 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400396 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400397 {
398 SafeDelete(framebuffer.second);
399 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 }
401
Corentin Wallez80b24112015-08-25 16:41:57 -0400402 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400404 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000405 }
406
Corentin Wallez80b24112015-08-25 16:41:57 -0400407 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400409 if (query.second != nullptr)
410 {
411 query.second->release();
412 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000413 }
414
Corentin Wallez80b24112015-08-25 16:41:57 -0400415 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400416 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400417 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400418 }
419
Corentin Wallez80b24112015-08-25 16:41:57 -0400420 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500421 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500422 if (transformFeedback.second != nullptr)
423 {
424 transformFeedback.second->release();
425 }
Geoff Langc8058452014-02-03 12:04:11 -0500426 }
427
Jamie Madilldedd7b92014-11-05 16:30:36 -0500428 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400429 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500430 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400431 }
432 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433
Corentin Wallez51706ea2015-08-07 14:39:22 -0400434 if (mCurrentSurface != nullptr)
435 {
436 releaseSurface();
437 }
438
Jamie Madill1e9ae072014-11-06 15:27:21 -0500439 if (mResourceManager)
440 {
441 mResourceManager->release();
442 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500443
444 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000445}
446
daniel@transgaming.comad629872012-11-28 19:32:06 +0000447void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000448{
Jamie Madill77a72f62015-04-14 11:18:32 -0400449 ASSERT(surface != nullptr);
450
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451 if (!mHasBeenCurrent)
452 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000453 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400454 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000455
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700456 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
457 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458
459 mHasBeenCurrent = true;
460 }
461
Jamie Madill1b94d432015-08-07 13:23:23 -0400462 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700463 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400464
Corentin Wallez51706ea2015-08-07 14:39:22 -0400465 if (mCurrentSurface)
466 {
467 releaseSurface();
468 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000469 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000471
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 // Update default framebuffer, the binding of the previous default
473 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400474 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400475 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700476 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700482 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400483 }
484 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400485 }
Ian Ewell292f0052016-02-04 10:37:32 -0500486
487 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700488 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000489}
490
Jamie Madill77a72f62015-04-14 11:18:32 -0400491void Context::releaseSurface()
492{
Corentin Wallez37c39792015-08-20 14:19:46 -0400493 ASSERT(mCurrentSurface != nullptr);
494
495 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400496 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700498 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700500 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400501 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700502 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400503 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700504 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400505 }
506 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400507 }
508
Corentin Wallez51706ea2015-08-07 14:39:22 -0400509 mCurrentSurface->setIsCurrent(false);
510 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400511}
512
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000513GLuint Context::createBuffer()
514{
515 return mResourceManager->createBuffer();
516}
517
518GLuint Context::createProgram()
519{
Jamie Madill901b3792016-05-26 09:20:40 -0400520 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000521}
522
523GLuint Context::createShader(GLenum type)
524{
Jamie Madill901b3792016-05-26 09:20:40 -0400525 return mResourceManager->createShader(mImplementation.get(),
526 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000527}
528
529GLuint Context::createTexture()
530{
531 return mResourceManager->createTexture();
532}
533
534GLuint Context::createRenderbuffer()
535{
536 return mResourceManager->createRenderbuffer();
537}
538
Geoff Lang882033e2014-09-30 11:26:07 -0400539GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400540{
Jamie Madill901b3792016-05-26 09:20:40 -0400541 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400542
Cooper Partind8e62a32015-01-29 15:21:25 -0800543 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400544}
545
Sami Väisänene45e53b2016-05-25 10:36:04 +0300546GLuint Context::createPaths(GLsizei range)
547{
548 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
549 if (resultOrError.isError())
550 {
551 handleError(resultOrError.getError());
552 return 0;
553 }
554 return resultOrError.getResult();
555}
556
Jamie Madill57a89722013-07-02 11:57:03 -0400557GLuint Context::createVertexArray()
558{
Geoff Lang36167ab2015-12-07 10:27:14 -0500559 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
560 mVertexArrayMap[vertexArray] = nullptr;
561 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400562}
563
Jamie Madilldc356042013-07-19 16:36:57 -0400564GLuint Context::createSampler()
565{
566 return mResourceManager->createSampler();
567}
568
Geoff Langc8058452014-02-03 12:04:11 -0500569GLuint Context::createTransformFeedback()
570{
Geoff Lang36167ab2015-12-07 10:27:14 -0500571 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
572 mTransformFeedbackMap[transformFeedback] = nullptr;
573 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500574}
575
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576// Returns an unused framebuffer name
577GLuint Context::createFramebuffer()
578{
579 GLuint handle = mFramebufferHandleAllocator.allocate();
580
581 mFramebufferMap[handle] = NULL;
582
583 return handle;
584}
585
Jamie Madill33dc8432013-07-26 11:55:05 -0400586GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587{
Jamie Madill33dc8432013-07-26 11:55:05 -0400588 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400590 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591
592 return handle;
593}
594
595// Returns an unused query name
596GLuint Context::createQuery()
597{
598 GLuint handle = mQueryHandleAllocator.allocate();
599
600 mQueryMap[handle] = NULL;
601
602 return handle;
603}
604
605void Context::deleteBuffer(GLuint buffer)
606{
607 if (mResourceManager->getBuffer(buffer))
608 {
609 detachBuffer(buffer);
610 }
Jamie Madill893ab082014-05-16 16:56:10 -0400611
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000612 mResourceManager->deleteBuffer(buffer);
613}
614
615void Context::deleteShader(GLuint shader)
616{
617 mResourceManager->deleteShader(shader);
618}
619
620void Context::deleteProgram(GLuint program)
621{
622 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000623}
624
625void Context::deleteTexture(GLuint texture)
626{
627 if (mResourceManager->getTexture(texture))
628 {
629 detachTexture(texture);
630 }
631
632 mResourceManager->deleteTexture(texture);
633}
634
635void Context::deleteRenderbuffer(GLuint renderbuffer)
636{
637 if (mResourceManager->getRenderbuffer(renderbuffer))
638 {
639 detachRenderbuffer(renderbuffer);
640 }
Jamie Madill893ab082014-05-16 16:56:10 -0400641
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642 mResourceManager->deleteRenderbuffer(renderbuffer);
643}
644
Jamie Madillcd055f82013-07-26 11:55:15 -0400645void Context::deleteFenceSync(GLsync fenceSync)
646{
647 // The spec specifies the underlying Fence object is not deleted until all current
648 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
649 // and since our API is currently designed for being called from a single thread, we can delete
650 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700651 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400652}
653
Sami Väisänene45e53b2016-05-25 10:36:04 +0300654void Context::deletePaths(GLuint first, GLsizei range)
655{
656 mResourceManager->deletePaths(first, range);
657}
658
659bool Context::hasPathData(GLuint path) const
660{
661 const auto *pathObj = mResourceManager->getPath(path);
662 if (pathObj == nullptr)
663 return false;
664
665 return pathObj->hasPathData();
666}
667
668bool Context::hasPath(GLuint path) const
669{
670 return mResourceManager->hasPath(path);
671}
672
673void Context::setPathCommands(GLuint path,
674 GLsizei numCommands,
675 const GLubyte *commands,
676 GLsizei numCoords,
677 GLenum coordType,
678 const void *coords)
679{
680 auto *pathObject = mResourceManager->getPath(path);
681
682 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
683}
684
685void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
686{
687 auto *pathObj = mResourceManager->getPath(path);
688
689 switch (pname)
690 {
691 case GL_PATH_STROKE_WIDTH_CHROMIUM:
692 pathObj->setStrokeWidth(value);
693 break;
694 case GL_PATH_END_CAPS_CHROMIUM:
695 pathObj->setEndCaps(static_cast<GLenum>(value));
696 break;
697 case GL_PATH_JOIN_STYLE_CHROMIUM:
698 pathObj->setJoinStyle(static_cast<GLenum>(value));
699 break;
700 case GL_PATH_MITER_LIMIT_CHROMIUM:
701 pathObj->setMiterLimit(value);
702 break;
703 case GL_PATH_STROKE_BOUND_CHROMIUM:
704 pathObj->setStrokeBound(value);
705 break;
706 default:
707 UNREACHABLE();
708 break;
709 }
710}
711
712void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
713{
714 const auto *pathObj = mResourceManager->getPath(path);
715
716 switch (pname)
717 {
718 case GL_PATH_STROKE_WIDTH_CHROMIUM:
719 *value = pathObj->getStrokeWidth();
720 break;
721 case GL_PATH_END_CAPS_CHROMIUM:
722 *value = static_cast<GLfloat>(pathObj->getEndCaps());
723 break;
724 case GL_PATH_JOIN_STYLE_CHROMIUM:
725 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
726 break;
727 case GL_PATH_MITER_LIMIT_CHROMIUM:
728 *value = pathObj->getMiterLimit();
729 break;
730 case GL_PATH_STROKE_BOUND_CHROMIUM:
731 *value = pathObj->getStrokeBound();
732 break;
733 default:
734 UNREACHABLE();
735 break;
736 }
737}
738
739void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
740{
741 mGLState.setPathStencilFunc(func, ref, mask);
742}
743
Jamie Madill57a89722013-07-02 11:57:03 -0400744void Context::deleteVertexArray(GLuint vertexArray)
745{
Geoff Lang36167ab2015-12-07 10:27:14 -0500746 auto iter = mVertexArrayMap.find(vertexArray);
747 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000748 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500749 VertexArray *vertexArrayObject = iter->second;
750 if (vertexArrayObject != nullptr)
751 {
752 detachVertexArray(vertexArray);
753 delete vertexArrayObject;
754 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000755
Geoff Lang36167ab2015-12-07 10:27:14 -0500756 mVertexArrayMap.erase(iter);
757 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400758 }
759}
760
Jamie Madilldc356042013-07-19 16:36:57 -0400761void Context::deleteSampler(GLuint sampler)
762{
763 if (mResourceManager->getSampler(sampler))
764 {
765 detachSampler(sampler);
766 }
767
768 mResourceManager->deleteSampler(sampler);
769}
770
Geoff Langc8058452014-02-03 12:04:11 -0500771void Context::deleteTransformFeedback(GLuint transformFeedback)
772{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500773 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500774 if (iter != mTransformFeedbackMap.end())
775 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500776 TransformFeedback *transformFeedbackObject = iter->second;
777 if (transformFeedbackObject != nullptr)
778 {
779 detachTransformFeedback(transformFeedback);
780 transformFeedbackObject->release();
781 }
782
Geoff Lang50b3fe82015-12-08 14:49:12 +0000783 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500784 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500785 }
786}
787
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788void Context::deleteFramebuffer(GLuint framebuffer)
789{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500790 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791
792 if (framebufferObject != mFramebufferMap.end())
793 {
794 detachFramebuffer(framebuffer);
795
796 mFramebufferHandleAllocator.release(framebufferObject->first);
797 delete framebufferObject->second;
798 mFramebufferMap.erase(framebufferObject);
799 }
800}
801
Jamie Madill33dc8432013-07-26 11:55:05 -0400802void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500804 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805
Jamie Madill33dc8432013-07-26 11:55:05 -0400806 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400808 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400810 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811 }
812}
813
814void Context::deleteQuery(GLuint query)
815{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500816 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817 if (queryObject != mQueryMap.end())
818 {
819 mQueryHandleAllocator.release(queryObject->first);
820 if (queryObject->second)
821 {
822 queryObject->second->release();
823 }
824 mQueryMap.erase(queryObject);
825 }
826}
827
Geoff Lang70d0f492015-12-10 17:45:46 -0500828Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829{
830 return mResourceManager->getBuffer(handle);
831}
832
Jamie Madill570f7c82014-07-03 10:38:54 -0400833Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834{
835 return mResourceManager->getTexture(handle);
836}
837
Geoff Lang70d0f492015-12-10 17:45:46 -0500838Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000839{
840 return mResourceManager->getRenderbuffer(handle);
841}
842
Jamie Madillcd055f82013-07-26 11:55:15 -0400843FenceSync *Context::getFenceSync(GLsync handle) const
844{
Minmin Gong794e0002015-04-07 18:31:54 -0700845 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400846}
847
Jamie Madill57a89722013-07-02 11:57:03 -0400848VertexArray *Context::getVertexArray(GLuint handle) const
849{
850 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500851 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400852}
853
Jamie Madilldc356042013-07-19 16:36:57 -0400854Sampler *Context::getSampler(GLuint handle) const
855{
856 return mResourceManager->getSampler(handle);
857}
858
Geoff Langc8058452014-02-03 12:04:11 -0500859TransformFeedback *Context::getTransformFeedback(GLuint handle) const
860{
Geoff Lang36167ab2015-12-07 10:27:14 -0500861 auto iter = mTransformFeedbackMap.find(handle);
862 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500863}
864
Geoff Lang70d0f492015-12-10 17:45:46 -0500865LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
866{
867 switch (identifier)
868 {
869 case GL_BUFFER:
870 return getBuffer(name);
871 case GL_SHADER:
872 return getShader(name);
873 case GL_PROGRAM:
874 return getProgram(name);
875 case GL_VERTEX_ARRAY:
876 return getVertexArray(name);
877 case GL_QUERY:
878 return getQuery(name);
879 case GL_TRANSFORM_FEEDBACK:
880 return getTransformFeedback(name);
881 case GL_SAMPLER:
882 return getSampler(name);
883 case GL_TEXTURE:
884 return getTexture(name);
885 case GL_RENDERBUFFER:
886 return getRenderbuffer(name);
887 case GL_FRAMEBUFFER:
888 return getFramebuffer(name);
889 default:
890 UNREACHABLE();
891 return nullptr;
892 }
893}
894
895LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
896{
897 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
898}
899
Martin Radev9d901792016-07-15 15:58:58 +0300900void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
901{
902 LabeledObject *object = getLabeledObject(identifier, name);
903 ASSERT(object != nullptr);
904
905 std::string labelName = GetObjectLabelFromPointer(length, label);
906 object->setLabel(labelName);
907}
908
909void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
910{
911 LabeledObject *object = getLabeledObjectFromPtr(ptr);
912 ASSERT(object != nullptr);
913
914 std::string labelName = GetObjectLabelFromPointer(length, label);
915 object->setLabel(labelName);
916}
917
918void Context::getObjectLabel(GLenum identifier,
919 GLuint name,
920 GLsizei bufSize,
921 GLsizei *length,
922 GLchar *label) const
923{
924 LabeledObject *object = getLabeledObject(identifier, name);
925 ASSERT(object != nullptr);
926
927 const std::string &objectLabel = object->getLabel();
928 GetObjectLabelBase(objectLabel, bufSize, length, label);
929}
930
931void Context::getObjectPtrLabel(const void *ptr,
932 GLsizei bufSize,
933 GLsizei *length,
934 GLchar *label) const
935{
936 LabeledObject *object = getLabeledObjectFromPtr(ptr);
937 ASSERT(object != nullptr);
938
939 const std::string &objectLabel = object->getLabel();
940 GetObjectLabelBase(objectLabel, bufSize, length, label);
941}
942
Jamie Madilldc356042013-07-19 16:36:57 -0400943bool Context::isSampler(GLuint samplerName) const
944{
945 return mResourceManager->isSampler(samplerName);
946}
947
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500948void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949{
Jamie Madill901b3792016-05-26 09:20:40 -0400950 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700951 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952}
953
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500954void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955{
Jamie Madill901b3792016-05-26 09:20:40 -0400956 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700957 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958}
959
Jamie Madilldedd7b92014-11-05 16:30:36 -0500960void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500962 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000963
Jamie Madilldedd7b92014-11-05 16:30:36 -0500964 if (handle == 0)
965 {
966 texture = mZeroTextures[target].get();
967 }
968 else
969 {
Jamie Madill901b3792016-05-26 09:20:40 -0400970 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500971 }
972
973 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700974 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000975}
976
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500977void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500979 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700980 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981}
982
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500983void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500985 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400990{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500991 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400996{
Geoff Lang76b10c92014-09-05 16:28:14 -0400997 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400998 Sampler *sampler =
999 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001004{
Jamie Madill901b3792016-05-26 09:20:40 -04001005 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1010 GLuint index,
1011 GLintptr offset,
1012 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001013{
Jamie Madill901b3792016-05-26 09:20:40 -04001014 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001015 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1025 GLuint index,
1026 GLintptr offset,
1027 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028{
Jamie Madill901b3792016-05-26 09:20:40 -04001029 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040{
Jamie Madill901b3792016-05-26 09:20:40 -04001041 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001046{
Jamie Madill901b3792016-05-26 09:20:40 -04001047 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052{
Jamie Madill901b3792016-05-26 09:20:40 -04001053 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001054 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001055}
1056
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001057void Context::useProgram(GLuint program)
1058{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001059 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001063{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001064 TransformFeedback *transformFeedback =
1065 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001066 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001067}
1068
Geoff Lang5aad9672014-09-08 11:10:42 -04001069Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001072 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001073
Geoff Lang5aad9672014-09-08 11:10:42 -04001074 // begin query
1075 Error error = queryObject->begin();
1076 if (error.isError())
1077 {
1078 return error;
1079 }
1080
1081 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085}
1086
Geoff Lang5aad9672014-09-08 11:10:42 -04001087Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001089 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001090 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093
Geoff Lang5aad9672014-09-08 11:10:42 -04001094 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001096
1097 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098}
1099
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001100Error Context::queryCounter(GLuint id, GLenum target)
1101{
1102 ASSERT(target == GL_TIMESTAMP_EXT);
1103
1104 Query *queryObject = getQuery(id, true, target);
1105 ASSERT(queryObject);
1106
1107 return queryObject->queryCounter();
1108}
1109
1110void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1111{
1112 switch (pname)
1113 {
1114 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001115 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001116 break;
1117 case GL_QUERY_COUNTER_BITS_EXT:
1118 switch (target)
1119 {
1120 case GL_TIME_ELAPSED_EXT:
1121 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1122 break;
1123 case GL_TIMESTAMP_EXT:
1124 params[0] = getExtensions().queryCounterBitsTimestamp;
1125 break;
1126 default:
1127 UNREACHABLE();
1128 params[0] = 0;
1129 break;
1130 }
1131 break;
1132 default:
1133 UNREACHABLE();
1134 return;
1135 }
1136}
1137
Geoff Lang2186c382016-10-14 10:54:54 -04001138void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001139{
Geoff Lang2186c382016-10-14 10:54:54 -04001140 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001141}
1142
Geoff Lang2186c382016-10-14 10:54:54 -04001143void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001144{
Geoff Lang2186c382016-10-14 10:54:54 -04001145 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001146}
1147
Geoff Lang2186c382016-10-14 10:54:54 -04001148void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001149{
Geoff Lang2186c382016-10-14 10:54:54 -04001150 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001151}
1152
Geoff Lang2186c382016-10-14 10:54:54 -04001153void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154{
Geoff Lang2186c382016-10-14 10:54:54 -04001155 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156}
1157
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001158Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001160 auto framebufferIt = mFramebufferMap.find(handle);
1161 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162}
1163
Jamie Madill33dc8432013-07-26 11:55:05 -04001164FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001166 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167
Jamie Madill33dc8432013-07-26 11:55:05 -04001168 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169 {
1170 return NULL;
1171 }
1172 else
1173 {
1174 return fence->second;
1175 }
1176}
1177
1178Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1179{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001180 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181
1182 if (query == mQueryMap.end())
1183 {
1184 return NULL;
1185 }
1186 else
1187 {
1188 if (!query->second && create)
1189 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001190 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191 query->second->addRef();
1192 }
1193 return query->second;
1194 }
1195}
1196
Geoff Lang70d0f492015-12-10 17:45:46 -05001197Query *Context::getQuery(GLuint handle) const
1198{
1199 auto iter = mQueryMap.find(handle);
1200 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1201}
1202
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001203Texture *Context::getTargetTexture(GLenum target) const
1204{
Ian Ewellbda75592016-04-18 17:25:54 -04001205 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001206 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001207}
1208
Geoff Lang76b10c92014-09-05 16:28:14 -04001209Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001211 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212}
1213
Geoff Lang492a7e42014-11-05 13:27:06 -05001214Compiler *Context::getCompiler() const
1215{
1216 return mCompiler;
1217}
1218
Jamie Madill893ab082014-05-16 16:56:10 -04001219void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
1221 switch (pname)
1222 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001223 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001224 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001226 mGLState.getBooleanv(pname, params);
1227 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229}
1230
Jamie Madill893ab082014-05-16 16:56:10 -04001231void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232{
Shannon Woods53a94a82014-06-24 15:20:36 -04001233 // Queries about context capabilities and maximums are answered by Context.
1234 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 switch (pname)
1236 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001238 params[0] = mCaps.minAliasedLineWidth;
1239 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 break;
1241 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001242 params[0] = mCaps.minAliasedPointSize;
1243 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001245 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001246 ASSERT(mExtensions.textureFilterAnisotropic);
1247 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001248 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001249 case GL_MAX_TEXTURE_LOD_BIAS:
1250 *params = mCaps.maxLODBias;
1251 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001252
1253 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1254 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1255 {
1256 ASSERT(mExtensions.pathRendering);
1257 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1258 memcpy(params, m, 16 * sizeof(GLfloat));
1259 }
1260 break;
1261
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001263 mGLState.getFloatv(pname, params);
1264 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266}
1267
Jamie Madill893ab082014-05-16 16:56:10 -04001268void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269{
Shannon Woods53a94a82014-06-24 15:20:36 -04001270 // Queries about context capabilities and maximums are answered by Context.
1271 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001272
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 switch (pname)
1274 {
Geoff Lang301d1612014-07-09 10:34:37 -04001275 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1276 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1277 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001278 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1279 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1280 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001281 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1282 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1283 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001284 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001285 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1286 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1287 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001288 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001289 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001290 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1291 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1292 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1293 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001294 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1295 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001296 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1297 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001298 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001299 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1300 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1301 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1302 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001303 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001304 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001305 break;
1306 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001307 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001308 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001309 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1310 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001311 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1312 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1313 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001314 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1315 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1316 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001317 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318 case GL_MAX_VIEWPORT_DIMS:
1319 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001320 params[0] = mCaps.maxViewportWidth;
1321 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 }
1323 break;
1324 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001325 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1328 *params = mResetStrategy;
1329 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001330 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001331 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001333 case GL_SHADER_BINARY_FORMATS:
1334 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1335 break;
1336 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001337 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001338 break;
1339 case GL_PROGRAM_BINARY_FORMATS:
1340 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001341 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001342 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001343 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001344 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001345
1346 // GL_KHR_debug
1347 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1348 *params = mExtensions.maxDebugMessageLength;
1349 break;
1350 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1351 *params = mExtensions.maxDebugLoggedMessages;
1352 break;
1353 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1354 *params = mExtensions.maxDebugGroupStackDepth;
1355 break;
1356 case GL_MAX_LABEL_LENGTH:
1357 *params = mExtensions.maxLabelLength;
1358 break;
1359
Ian Ewell53f59f42016-01-28 17:36:55 -05001360 // GL_EXT_disjoint_timer_query
1361 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001362 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001363 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001364 case GL_MAX_FRAMEBUFFER_WIDTH:
1365 *params = mCaps.maxFramebufferWidth;
1366 break;
1367 case GL_MAX_FRAMEBUFFER_HEIGHT:
1368 *params = mCaps.maxFramebufferHeight;
1369 break;
1370 case GL_MAX_FRAMEBUFFER_SAMPLES:
1371 *params = mCaps.maxFramebufferSamples;
1372 break;
1373 case GL_MAX_SAMPLE_MASK_WORDS:
1374 *params = mCaps.maxSampleMaskWords;
1375 break;
1376 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1377 *params = mCaps.maxColorTextureSamples;
1378 break;
1379 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1380 *params = mCaps.maxDepthTextureSamples;
1381 break;
1382 case GL_MAX_INTEGER_SAMPLES:
1383 *params = mCaps.maxIntegerSamples;
1384 break;
1385 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1386 *params = mCaps.maxVertexAttribRelativeOffset;
1387 break;
1388 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1389 *params = mCaps.maxVertexAttribBindings;
1390 break;
1391 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1392 *params = mCaps.maxVertexAttribStride;
1393 break;
1394 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1395 *params = mCaps.maxVertexAtomicCounterBuffers;
1396 break;
1397 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1398 *params = mCaps.maxVertexAtomicCounters;
1399 break;
1400 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1401 *params = mCaps.maxVertexImageUniforms;
1402 break;
1403 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1404 *params = mCaps.maxVertexShaderStorageBlocks;
1405 break;
1406 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1407 *params = mCaps.maxFragmentAtomicCounterBuffers;
1408 break;
1409 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1410 *params = mCaps.maxFragmentAtomicCounters;
1411 break;
1412 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1413 *params = mCaps.maxFragmentImageUniforms;
1414 break;
1415 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1416 *params = mCaps.maxFragmentShaderStorageBlocks;
1417 break;
1418 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1419 *params = mCaps.minProgramTextureGatherOffset;
1420 break;
1421 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1422 *params = mCaps.maxProgramTextureGatherOffset;
1423 break;
1424 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1425 *params = mCaps.maxComputeWorkGroupInvocations;
1426 break;
1427 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1428 *params = mCaps.maxComputeUniformBlocks;
1429 break;
1430 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1431 *params = mCaps.maxComputeTextureImageUnits;
1432 break;
1433 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1434 *params = mCaps.maxComputeSharedMemorySize;
1435 break;
1436 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1437 *params = mCaps.maxComputeUniformComponents;
1438 break;
1439 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1440 *params = mCaps.maxComputeAtomicCounterBuffers;
1441 break;
1442 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1443 *params = mCaps.maxComputeAtomicCounters;
1444 break;
1445 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1446 *params = mCaps.maxComputeImageUniforms;
1447 break;
1448 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1449 *params = mCaps.maxCombinedComputeUniformComponents;
1450 break;
1451 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1452 *params = mCaps.maxComputeShaderStorageBlocks;
1453 break;
1454 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1455 *params = mCaps.maxCombinedShaderOutputResources;
1456 break;
1457 case GL_MAX_UNIFORM_LOCATIONS:
1458 *params = mCaps.maxUniformLocations;
1459 break;
1460 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1461 *params = mCaps.maxAtomicCounterBufferBindings;
1462 break;
1463 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1464 *params = mCaps.maxAtomicCounterBufferSize;
1465 break;
1466 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1467 *params = mCaps.maxCombinedAtomicCounterBuffers;
1468 break;
1469 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1470 *params = mCaps.maxCombinedAtomicCounters;
1471 break;
1472 case GL_MAX_IMAGE_UNITS:
1473 *params = mCaps.maxImageUnits;
1474 break;
1475 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1476 *params = mCaps.maxCombinedImageUniforms;
1477 break;
1478 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1479 *params = mCaps.maxShaderStorageBufferBindings;
1480 break;
1481 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1482 *params = mCaps.maxCombinedShaderStorageBlocks;
1483 break;
1484 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1485 *params = mCaps.shaderStorageBufferOffsetAlignment;
1486 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001488 mGLState.getIntegerv(mState, pname, params);
1489 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001490 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491}
1492
Jamie Madill893ab082014-05-16 16:56:10 -04001493void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001494{
Shannon Woods53a94a82014-06-24 15:20:36 -04001495 // Queries about context capabilities and maximums are answered by Context.
1496 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001497 switch (pname)
1498 {
1499 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001500 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 break;
1502 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001503 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001504 break;
1505 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001506 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001509 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
1511 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001512 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001514
1515 // GL_EXT_disjoint_timer_query
1516 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001517 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001518 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001519
1520 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1521 *params = mCaps.maxShaderStorageBlockSize;
1522 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001524 UNREACHABLE();
1525 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001526 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001527}
1528
Geoff Lang70d0f492015-12-10 17:45:46 -05001529void Context::getPointerv(GLenum pname, void **params) const
1530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001531 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001532}
1533
Martin Radev66fb8202016-07-28 11:45:20 +03001534void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001535{
Shannon Woods53a94a82014-06-24 15:20:36 -04001536 // Queries about context capabilities and maximums are answered by Context.
1537 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001538
1539 GLenum nativeType;
1540 unsigned int numParams;
1541 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1542 ASSERT(queryStatus);
1543
1544 if (nativeType == GL_INT)
1545 {
1546 switch (target)
1547 {
1548 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1549 ASSERT(index < 3u);
1550 *data = mCaps.maxComputeWorkGroupCount[index];
1551 break;
1552 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1553 ASSERT(index < 3u);
1554 *data = mCaps.maxComputeWorkGroupSize[index];
1555 break;
1556 default:
1557 mGLState.getIntegeri_v(target, index, data);
1558 }
1559 }
1560 else
1561 {
1562 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1563 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001564}
1565
Martin Radev66fb8202016-07-28 11:45:20 +03001566void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001567{
Shannon Woods53a94a82014-06-24 15:20:36 -04001568 // Queries about context capabilities and maximums are answered by Context.
1569 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001570
1571 GLenum nativeType;
1572 unsigned int numParams;
1573 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1574 ASSERT(queryStatus);
1575
1576 if (nativeType == GL_INT_64_ANGLEX)
1577 {
1578 mGLState.getInteger64i_v(target, index, data);
1579 }
1580 else
1581 {
1582 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1583 }
1584}
1585
1586void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1587{
1588 // Queries about context capabilities and maximums are answered by Context.
1589 // Queries about current GL state values are answered by State.
1590
1591 GLenum nativeType;
1592 unsigned int numParams;
1593 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1594 ASSERT(queryStatus);
1595
1596 if (nativeType == GL_BOOL)
1597 {
1598 mGLState.getBooleani_v(target, index, data);
1599 }
1600 else
1601 {
1602 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1603 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001604}
1605
Geoff Langf6db0982015-08-25 13:04:00 -04001606Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607{
Jamie Madill1b94d432015-08-07 13:23:23 -04001608 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001609 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001610 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001611
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001612 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Geoff Langf6db0982015-08-25 13:04:00 -04001615Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1616{
1617 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001619 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001620
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001621 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001622}
1623
1624Error Context::drawElements(GLenum mode,
1625 GLsizei count,
1626 GLenum type,
1627 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001628 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629{
Jamie Madill1b94d432015-08-07 13:23:23 -04001630 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001631 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001632}
1633
1634Error Context::drawElementsInstanced(GLenum mode,
1635 GLsizei count,
1636 GLenum type,
1637 const GLvoid *indices,
1638 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001639 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001640{
1641 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001642 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1643 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001644}
1645
1646Error Context::drawRangeElements(GLenum mode,
1647 GLuint start,
1648 GLuint end,
1649 GLsizei count,
1650 GLenum type,
1651 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001652 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001653{
1654 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001655 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656}
1657
Geoff Lang129753a2015-01-09 16:52:09 -05001658Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001660 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001661}
1662
1663Error Context::finish()
1664{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001665 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666}
1667
Austin Kinross6ee1e782015-05-29 17:05:37 -07001668void Context::insertEventMarker(GLsizei length, const char *marker)
1669{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001670 ASSERT(mImplementation);
1671 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001672}
1673
1674void Context::pushGroupMarker(GLsizei length, const char *marker)
1675{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001676 ASSERT(mImplementation);
1677 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001678}
1679
1680void Context::popGroupMarker()
1681{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001682 ASSERT(mImplementation);
1683 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001684}
1685
Geoff Langd8605522016-04-13 10:19:12 -04001686void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1687{
1688 Program *programObject = getProgram(program);
1689 ASSERT(programObject);
1690
1691 programObject->bindUniformLocation(location, name);
1692}
1693
Sami Väisänena797e062016-05-12 15:23:40 +03001694void Context::setCoverageModulation(GLenum components)
1695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001696 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001697}
1698
Sami Väisänene45e53b2016-05-25 10:36:04 +03001699void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1700{
1701 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1702}
1703
1704void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1705{
1706 GLfloat I[16];
1707 angle::Matrix<GLfloat>::setToIdentity(I);
1708
1709 mGLState.loadPathRenderingMatrix(matrixMode, I);
1710}
1711
1712void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1713{
1714 const auto *pathObj = mResourceManager->getPath(path);
1715 if (!pathObj)
1716 return;
1717
1718 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1719 syncRendererState();
1720
1721 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1722}
1723
1724void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1725{
1726 const auto *pathObj = mResourceManager->getPath(path);
1727 if (!pathObj)
1728 return;
1729
1730 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1731 syncRendererState();
1732
1733 mImplementation->stencilStrokePath(pathObj, reference, mask);
1734}
1735
1736void Context::coverFillPath(GLuint path, GLenum coverMode)
1737{
1738 const auto *pathObj = mResourceManager->getPath(path);
1739 if (!pathObj)
1740 return;
1741
1742 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1743 syncRendererState();
1744
1745 mImplementation->coverFillPath(pathObj, coverMode);
1746}
1747
1748void Context::coverStrokePath(GLuint path, GLenum coverMode)
1749{
1750 const auto *pathObj = mResourceManager->getPath(path);
1751 if (!pathObj)
1752 return;
1753
1754 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1755 syncRendererState();
1756
1757 mImplementation->coverStrokePath(pathObj, coverMode);
1758}
1759
1760void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1761{
1762 const auto *pathObj = mResourceManager->getPath(path);
1763 if (!pathObj)
1764 return;
1765
1766 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1767 syncRendererState();
1768
1769 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1770}
1771
1772void Context::stencilThenCoverStrokePath(GLuint path,
1773 GLint reference,
1774 GLuint mask,
1775 GLenum coverMode)
1776{
1777 const auto *pathObj = mResourceManager->getPath(path);
1778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1785}
1786
Sami Väisänend59ca052016-06-21 16:10:00 +03001787void Context::coverFillPathInstanced(GLsizei numPaths,
1788 GLenum pathNameType,
1789 const void *paths,
1790 GLuint pathBase,
1791 GLenum coverMode,
1792 GLenum transformType,
1793 const GLfloat *transformValues)
1794{
1795 const auto &pathObjects =
1796 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1797
1798 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1799 syncRendererState();
1800
1801 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1802}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001803
Sami Väisänend59ca052016-06-21 16:10:00 +03001804void Context::coverStrokePathInstanced(GLsizei numPaths,
1805 GLenum pathNameType,
1806 const void *paths,
1807 GLuint pathBase,
1808 GLenum coverMode,
1809 GLenum transformType,
1810 const GLfloat *transformValues)
1811{
1812 const auto &pathObjects =
1813 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1814
1815 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1816 syncRendererState();
1817
1818 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1819 transformValues);
1820}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001821
Sami Väisänend59ca052016-06-21 16:10:00 +03001822void Context::stencilFillPathInstanced(GLsizei numPaths,
1823 GLenum pathNameType,
1824 const void *paths,
1825 GLuint pathBase,
1826 GLenum fillMode,
1827 GLuint mask,
1828 GLenum transformType,
1829 const GLfloat *transformValues)
1830{
1831 const auto &pathObjects =
1832 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1833
1834 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1835 syncRendererState();
1836
1837 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1838 transformValues);
1839}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001840
Sami Väisänend59ca052016-06-21 16:10:00 +03001841void Context::stencilStrokePathInstanced(GLsizei numPaths,
1842 GLenum pathNameType,
1843 const void *paths,
1844 GLuint pathBase,
1845 GLint reference,
1846 GLuint mask,
1847 GLenum transformType,
1848 const GLfloat *transformValues)
1849{
1850 const auto &pathObjects =
1851 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1852
1853 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1854 syncRendererState();
1855
1856 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1857 transformValues);
1858}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001859
Sami Väisänend59ca052016-06-21 16:10:00 +03001860void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1861 GLenum pathNameType,
1862 const void *paths,
1863 GLuint pathBase,
1864 GLenum fillMode,
1865 GLuint mask,
1866 GLenum coverMode,
1867 GLenum transformType,
1868 const GLfloat *transformValues)
1869{
1870 const auto &pathObjects =
1871 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1872
1873 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1874 syncRendererState();
1875
1876 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1877 transformType, transformValues);
1878}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001879
Sami Väisänend59ca052016-06-21 16:10:00 +03001880void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1881 GLenum pathNameType,
1882 const void *paths,
1883 GLuint pathBase,
1884 GLint reference,
1885 GLuint mask,
1886 GLenum coverMode,
1887 GLenum transformType,
1888 const GLfloat *transformValues)
1889{
1890 const auto &pathObjects =
1891 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1897 transformType, transformValues);
1898}
1899
Sami Väisänen46eaa942016-06-29 10:26:37 +03001900void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1901{
1902 auto *programObject = getProgram(program);
1903
1904 programObject->bindFragmentInputLocation(location, name);
1905}
1906
1907void Context::programPathFragmentInputGen(GLuint program,
1908 GLint location,
1909 GLenum genMode,
1910 GLint components,
1911 const GLfloat *coeffs)
1912{
1913 auto *programObject = getProgram(program);
1914
1915 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1916}
1917
Jamie Madill437fa652016-05-03 15:13:24 -04001918void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001919{
Geoff Langda5777c2014-07-11 09:52:58 -04001920 if (error.isError())
1921 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001922 GLenum code = error.getCode();
1923 mErrors.insert(code);
1924 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1925 {
1926 markContextLost();
1927 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001928
1929 if (!error.getMessage().empty())
1930 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001931 auto *debug = &mGLState.getDebug();
1932 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1933 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001934 }
Geoff Langda5777c2014-07-11 09:52:58 -04001935 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936}
1937
1938// Get one of the recorded errors and clear its flag, if any.
1939// [OpenGL ES 2.0.24] section 2.5 page 13.
1940GLenum Context::getError()
1941{
Geoff Langda5777c2014-07-11 09:52:58 -04001942 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943 {
Geoff Langda5777c2014-07-11 09:52:58 -04001944 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945 }
Geoff Langda5777c2014-07-11 09:52:58 -04001946 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 {
Geoff Langda5777c2014-07-11 09:52:58 -04001948 GLenum error = *mErrors.begin();
1949 mErrors.erase(mErrors.begin());
1950 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952}
1953
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001954// NOTE: this function should not assume that this context is current!
1955void Context::markContextLost()
1956{
1957 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001958 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001959 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001960 mContextLostForced = true;
1961 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001962 mContextLost = true;
1963}
1964
1965bool Context::isContextLost()
1966{
1967 return mContextLost;
1968}
1969
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001970GLenum Context::getResetStatus()
1971{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001972 // Even if the application doesn't want to know about resets, we want to know
1973 // as it will allow us to skip all the calls.
1974 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001977 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001979 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980
1981 // EXT_robustness, section 2.6: If the reset notification behavior is
1982 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1983 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1984 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985 }
1986
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1988 // status should be returned at least once, and GL_NO_ERROR should be returned
1989 // once the device has finished resetting.
1990 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001992 ASSERT(mResetStatus == GL_NO_ERROR);
1993 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001994
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998 }
1999 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002000 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002002 // If markContextLost was used to mark the context lost then
2003 // assume that is not recoverable, and continue to report the
2004 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002005 mResetStatus = mImplementation->getResetStatus();
2006 }
Jamie Madill893ab082014-05-16 16:56:10 -04002007
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002009}
2010
2011bool Context::isResetNotificationEnabled()
2012{
2013 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2014}
2015
Corentin Walleze3b10e82015-05-20 11:06:25 -04002016const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002017{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002018 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002019}
2020
2021EGLenum Context::getClientType() const
2022{
2023 return mClientType;
2024}
2025
2026EGLenum Context::getRenderBuffer() const
2027{
Corentin Wallez37c39792015-08-20 14:19:46 -04002028 auto framebufferIt = mFramebufferMap.find(0);
2029 if (framebufferIt != mFramebufferMap.end())
2030 {
2031 const Framebuffer *framebuffer = framebufferIt->second;
2032 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2033
2034 ASSERT(backAttachment != nullptr);
2035 return backAttachment->getSurface()->getRenderBuffer();
2036 }
2037 else
2038 {
2039 return EGL_NONE;
2040 }
Régis Fénéon83107972015-02-05 12:57:44 +01002041}
2042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002043VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002044{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002045 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002046 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2047 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002049 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002051 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002052 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053
2054 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002055}
2056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002057TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002058{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002059 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2061 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002062 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002063 transformFeedback =
2064 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002065 transformFeedback->addRef();
2066 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002067 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068
2069 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070}
2071
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002072Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2073{
2074 // Can be called from Bind without a prior call to Gen.
2075 auto framebufferIt = mFramebufferMap.find(framebuffer);
2076 bool neverCreated = framebufferIt == mFramebufferMap.end();
2077 if (neverCreated || framebufferIt->second == nullptr)
2078 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002079 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002080 if (neverCreated)
2081 {
2082 mFramebufferHandleAllocator.reserve(framebuffer);
2083 mFramebufferMap[framebuffer] = newFBO;
2084 return newFBO;
2085 }
2086
2087 framebufferIt->second = newFBO;
2088 }
2089
2090 return framebufferIt->second;
2091}
2092
Geoff Lang36167ab2015-12-07 10:27:14 -05002093bool Context::isVertexArrayGenerated(GLuint vertexArray)
2094{
Geoff Langf41a7152016-09-19 15:11:17 -04002095 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002096 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2097}
2098
2099bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2100{
Geoff Langf41a7152016-09-19 15:11:17 -04002101 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002102 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2103}
2104
Shannon Woods53a94a82014-06-24 15:20:36 -04002105void Context::detachTexture(GLuint texture)
2106{
2107 // Simple pass-through to State's detachTexture method, as textures do not require
2108 // allocation map management either here or in the resource manager at detach time.
2109 // Zero textures are held by the Context, and we don't attempt to request them from
2110 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002111 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002112}
2113
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002114void Context::detachBuffer(GLuint buffer)
2115{
Yuly Novikov5807a532015-12-03 13:01:22 -05002116 // Simple pass-through to State's detachBuffer method, since
2117 // only buffer attachments to container objects that are bound to the current context
2118 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002119
Yuly Novikov5807a532015-12-03 13:01:22 -05002120 // [OpenGL ES 3.2] section 5.1.2 page 45:
2121 // Attachments to unbound container objects, such as
2122 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2123 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002124 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002125}
2126
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002127void Context::detachFramebuffer(GLuint framebuffer)
2128{
Shannon Woods53a94a82014-06-24 15:20:36 -04002129 // Framebuffer detachment is handled by Context, because 0 is a valid
2130 // Framebuffer object, and a pointer to it must be passed from Context
2131 // to State at binding time.
2132
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002133 // [OpenGL ES 2.0.24] section 4.4 page 107:
2134 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2135 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2136
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002137 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138 {
2139 bindReadFramebuffer(0);
2140 }
2141
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002142 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002143 {
2144 bindDrawFramebuffer(0);
2145 }
2146}
2147
2148void Context::detachRenderbuffer(GLuint renderbuffer)
2149{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002150 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002151}
2152
Jamie Madill57a89722013-07-02 11:57:03 -04002153void Context::detachVertexArray(GLuint vertexArray)
2154{
Jamie Madill77a72f62015-04-14 11:18:32 -04002155 // Vertex array detachment is handled by Context, because 0 is a valid
2156 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002157 // binding time.
2158
Jamie Madill57a89722013-07-02 11:57:03 -04002159 // [OpenGL ES 3.0.2] section 2.10 page 43:
2160 // If a vertex array object that is currently bound is deleted, the binding
2161 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002162 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002163 {
2164 bindVertexArray(0);
2165 }
2166}
2167
Geoff Langc8058452014-02-03 12:04:11 -05002168void Context::detachTransformFeedback(GLuint transformFeedback)
2169{
Corentin Walleza2257da2016-04-19 16:43:12 -04002170 // Transform feedback detachment is handled by Context, because 0 is a valid
2171 // transform feedback, and a pointer to it must be passed from Context to State at
2172 // binding time.
2173
2174 // The OpenGL specification doesn't mention what should happen when the currently bound
2175 // transform feedback object is deleted. Since it is a container object, we treat it like
2176 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002178 {
2179 bindTransformFeedback(0);
2180 }
Geoff Langc8058452014-02-03 12:04:11 -05002181}
2182
Jamie Madilldc356042013-07-19 16:36:57 -04002183void Context::detachSampler(GLuint sampler)
2184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002185 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002186}
2187
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002190 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002191}
2192
Jamie Madille29d1672013-07-19 16:36:57 -04002193void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2194{
Geoff Langc1984ed2016-10-07 12:41:00 -04002195 Sampler *samplerObject =
2196 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2197 SetSamplerParameteri(samplerObject, pname, param);
2198}
Jamie Madille29d1672013-07-19 16:36:57 -04002199
Geoff Langc1984ed2016-10-07 12:41:00 -04002200void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2201{
2202 Sampler *samplerObject =
2203 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2204 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002205}
2206
2207void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2208{
Geoff Langc1984ed2016-10-07 12:41:00 -04002209 Sampler *samplerObject =
2210 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2211 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002212}
2213
Geoff Langc1984ed2016-10-07 12:41:00 -04002214void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002215{
Geoff Langc1984ed2016-10-07 12:41:00 -04002216 Sampler *samplerObject =
2217 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2218 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002219}
2220
Geoff Langc1984ed2016-10-07 12:41:00 -04002221void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002222{
Geoff Langc1984ed2016-10-07 12:41:00 -04002223 const Sampler *samplerObject =
2224 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2225 QuerySamplerParameteriv(samplerObject, pname, params);
2226}
Jamie Madill9675b802013-07-19 16:36:59 -04002227
Geoff Langc1984ed2016-10-07 12:41:00 -04002228void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2229{
2230 const Sampler *samplerObject =
2231 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2232 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002233}
2234
Olli Etuahof0fee072016-03-30 15:11:58 +03002235void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2236{
2237 gl::Program *programObject = getProgram(program);
2238 ASSERT(programObject != nullptr);
2239
2240 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2241 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2242}
2243
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002244void Context::initRendererString()
2245{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002246 std::ostringstream rendererString;
2247 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002248 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002249 rendererString << ")";
2250
Geoff Langcec35902014-04-16 10:52:36 -04002251 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252}
2253
Geoff Langc287ea62016-09-16 14:46:51 -04002254const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002255{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002256 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002257}
2258
Geoff Langcec35902014-04-16 10:52:36 -04002259void Context::initExtensionStrings()
2260{
Geoff Langc287ea62016-09-16 14:46:51 -04002261 for (const auto &extensionString : mExtensions.getStrings())
2262 {
2263 mExtensionStrings.push_back(MakeStaticString(extensionString));
2264 }
Geoff Langcec35902014-04-16 10:52:36 -04002265
Geoff Langc0b9ef42014-07-02 10:02:37 -04002266 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002267 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2268 std::ostream_iterator<const char *>(combinedStringStream, " "));
2269 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002270}
2271
Geoff Langc287ea62016-09-16 14:46:51 -04002272const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002273{
2274 return mExtensionString;
2275}
2276
Geoff Langc287ea62016-09-16 14:46:51 -04002277const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002278{
2279 return mExtensionStrings[idx];
2280}
2281
2282size_t Context::getExtensionStringCount() const
2283{
2284 return mExtensionStrings.size();
2285}
2286
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002287void Context::beginTransformFeedback(GLenum primitiveMode)
2288{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002289 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002290 ASSERT(transformFeedback != nullptr);
2291 ASSERT(!transformFeedback->isPaused());
2292
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002293 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002294}
2295
2296bool Context::hasActiveTransformFeedback(GLuint program) const
2297{
2298 for (auto pair : mTransformFeedbackMap)
2299 {
2300 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2301 {
2302 return true;
2303 }
2304 }
2305 return false;
2306}
2307
Geoff Langc287ea62016-09-16 14:46:51 -04002308void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002309{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002310 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002311
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002312 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002313
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002314 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002315
Geoff Langeb66a6e2016-10-31 13:06:12 -04002316 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002317 {
2318 // Disable ES3+ extensions
2319 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002320 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002321 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002322 }
2323
Geoff Langeb66a6e2016-10-31 13:06:12 -04002324 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002325 {
2326 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2327 //mExtensions.sRGB = false;
2328 }
2329
Jamie Madill00ed7a12016-05-19 13:13:38 -04002330 // Some extensions are always available because they are implemented in the GL layer.
2331 mExtensions.bindUniformLocation = true;
2332 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002333 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002334
2335 // Enable the no error extension if the context was created with the flag.
2336 mExtensions.noError = mSkipValidation;
2337
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 // Explicitly enable GL_KHR_debug
2339 mExtensions.debug = true;
2340 mExtensions.maxDebugMessageLength = 1024;
2341 mExtensions.maxDebugLoggedMessages = 1024;
2342 mExtensions.maxDebugGroupStackDepth = 1024;
2343 mExtensions.maxLabelLength = 1024;
2344
Geoff Langff5b2d52016-09-07 11:32:23 -04002345 // Explicitly enable GL_ANGLE_robust_client_memory
2346 mExtensions.robustClientMemory = true;
2347
Geoff Lang301d1612014-07-09 10:34:37 -04002348 // Apply implementation limits
2349 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002350 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2351 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2352
2353 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002354
Geoff Langc287ea62016-09-16 14:46:51 -04002355 // WebGL compatibility
2356 mExtensions.webglCompatibility = webGLContext;
2357 for (const auto &extensionInfo : GetExtensionInfoMap())
2358 {
2359 // If this context is for WebGL, disable all enableable extensions
2360 if (webGLContext && extensionInfo.second.Enableable)
2361 {
2362 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2363 }
2364 }
2365
2366 // Generate texture caps
2367 updateCaps();
2368}
2369
2370void Context::updateCaps()
2371{
Geoff Lang900013c2014-07-07 11:32:19 -04002372 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002373 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002374
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002375 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002376 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2377 {
2378 GLenum format = i->first;
2379 TextureCaps formatCaps = i->second;
2380
Geoff Lang5d601382014-07-22 15:14:06 -04002381 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002382
Geoff Lang0d8b7242015-09-09 14:56:53 -04002383 // Update the format caps based on the client version and extensions.
2384 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2385 // ES3.
2386 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002387 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002388 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002389 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002390 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002391 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002392
2393 // OpenGL ES does not support multisampling with integer formats
2394 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002395 {
Geoff Langd87878e2014-09-19 15:42:59 -04002396 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002397 }
Geoff Langd87878e2014-09-19 15:42:59 -04002398
2399 if (formatCaps.texturable && formatInfo.compressed)
2400 {
2401 mCaps.compressedTextureFormats.push_back(format);
2402 }
2403
2404 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002405 }
2406}
2407
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002408void Context::initWorkarounds()
2409{
2410 // Lose the context upon out of memory error if the application is
2411 // expecting to watch for those events.
2412 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2413}
2414
Jamie Madill1b94d432015-08-07 13:23:23 -04002415void Context::syncRendererState()
2416{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002417 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2418 mImplementation->syncState(mGLState, dirtyBits);
2419 mGLState.clearDirtyBits();
2420 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002421}
2422
Jamie Madillad9f24e2016-02-12 09:27:24 -05002423void Context::syncRendererState(const State::DirtyBits &bitMask,
2424 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002425{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002426 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2427 mImplementation->syncState(mGLState, dirtyBits);
2428 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002429
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002430 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002431}
Jamie Madillc29968b2016-01-20 11:17:23 -05002432
2433void Context::blitFramebuffer(GLint srcX0,
2434 GLint srcY0,
2435 GLint srcX1,
2436 GLint srcY1,
2437 GLint dstX0,
2438 GLint dstY0,
2439 GLint dstX1,
2440 GLint dstY1,
2441 GLbitfield mask,
2442 GLenum filter)
2443{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002444 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002445 ASSERT(drawFramebuffer);
2446
2447 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2448 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2449
Jamie Madillad9f24e2016-02-12 09:27:24 -05002450 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002451
Jamie Madill8415b5f2016-04-26 13:41:39 -04002452 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002453}
Jamie Madillc29968b2016-01-20 11:17:23 -05002454
2455void Context::clear(GLbitfield mask)
2456{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002457 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002458 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002459}
2460
2461void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2462{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002463 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002464 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2465 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002466}
2467
2468void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2469{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002470 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002471 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2472 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002473}
2474
2475void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2476{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002477 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002478 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2479 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002480}
2481
2482void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002484 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002485 ASSERT(framebufferObject);
2486
2487 // If a buffer is not present, the clear has no effect
2488 if (framebufferObject->getDepthbuffer() == nullptr &&
2489 framebufferObject->getStencilbuffer() == nullptr)
2490 {
2491 return;
2492 }
2493
Jamie Madillad9f24e2016-02-12 09:27:24 -05002494 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002495 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2496 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002497}
2498
2499void Context::readPixels(GLint x,
2500 GLint y,
2501 GLsizei width,
2502 GLsizei height,
2503 GLenum format,
2504 GLenum type,
2505 GLvoid *pixels)
2506{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002507 if (width == 0 || height == 0)
2508 {
2509 return;
2510 }
2511
Jamie Madillad9f24e2016-02-12 09:27:24 -05002512 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002513
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002514 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002515 ASSERT(framebufferObject);
2516
2517 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002518 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002519}
2520
2521void Context::copyTexImage2D(GLenum target,
2522 GLint level,
2523 GLenum internalformat,
2524 GLint x,
2525 GLint y,
2526 GLsizei width,
2527 GLsizei height,
2528 GLint border)
2529{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002530 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002531 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002532
Jamie Madillc29968b2016-01-20 11:17:23 -05002533 Rectangle sourceArea(x, y, width, height);
2534
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002535 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002536 Texture *texture =
2537 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002538 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002539}
2540
2541void Context::copyTexSubImage2D(GLenum target,
2542 GLint level,
2543 GLint xoffset,
2544 GLint yoffset,
2545 GLint x,
2546 GLint y,
2547 GLsizei width,
2548 GLsizei height)
2549{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002550 if (width == 0 || height == 0)
2551 {
2552 return;
2553 }
2554
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002555 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002556 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002557
Jamie Madillc29968b2016-01-20 11:17:23 -05002558 Offset destOffset(xoffset, yoffset, 0);
2559 Rectangle sourceArea(x, y, width, height);
2560
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002561 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002562 Texture *texture =
2563 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002564 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002565}
2566
2567void Context::copyTexSubImage3D(GLenum target,
2568 GLint level,
2569 GLint xoffset,
2570 GLint yoffset,
2571 GLint zoffset,
2572 GLint x,
2573 GLint y,
2574 GLsizei width,
2575 GLsizei height)
2576{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002577 if (width == 0 || height == 0)
2578 {
2579 return;
2580 }
2581
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002582 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002583 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 Offset destOffset(xoffset, yoffset, zoffset);
2586 Rectangle sourceArea(x, y, width, height);
2587
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002588 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002590 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002591}
2592
2593void Context::framebufferTexture2D(GLenum target,
2594 GLenum attachment,
2595 GLenum textarget,
2596 GLuint texture,
2597 GLint level)
2598{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002599 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002600 ASSERT(framebuffer);
2601
2602 if (texture != 0)
2603 {
2604 Texture *textureObj = getTexture(texture);
2605
2606 ImageIndex index = ImageIndex::MakeInvalid();
2607
2608 if (textarget == GL_TEXTURE_2D)
2609 {
2610 index = ImageIndex::Make2D(level);
2611 }
2612 else
2613 {
2614 ASSERT(IsCubeMapTextureTarget(textarget));
2615 index = ImageIndex::MakeCube(textarget, level);
2616 }
2617
2618 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2619 }
2620 else
2621 {
2622 framebuffer->resetAttachment(attachment);
2623 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002624
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002626}
2627
2628void Context::framebufferRenderbuffer(GLenum target,
2629 GLenum attachment,
2630 GLenum renderbuffertarget,
2631 GLuint renderbuffer)
2632{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002633 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002634 ASSERT(framebuffer);
2635
2636 if (renderbuffer != 0)
2637 {
2638 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2639 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2640 renderbufferObject);
2641 }
2642 else
2643 {
2644 framebuffer->resetAttachment(attachment);
2645 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002646
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002647 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002648}
2649
2650void Context::framebufferTextureLayer(GLenum target,
2651 GLenum attachment,
2652 GLuint texture,
2653 GLint level,
2654 GLint layer)
2655{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002657 ASSERT(framebuffer);
2658
2659 if (texture != 0)
2660 {
2661 Texture *textureObject = getTexture(texture);
2662
2663 ImageIndex index = ImageIndex::MakeInvalid();
2664
2665 if (textureObject->getTarget() == GL_TEXTURE_3D)
2666 {
2667 index = ImageIndex::Make3D(level, layer);
2668 }
2669 else
2670 {
2671 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2672 index = ImageIndex::Make2DArray(level, layer);
2673 }
2674
2675 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2676 }
2677 else
2678 {
2679 framebuffer->resetAttachment(attachment);
2680 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002681
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002682 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002683}
2684
2685void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2686{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002687 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002688 ASSERT(framebuffer);
2689 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002691}
2692
2693void Context::readBuffer(GLenum mode)
2694{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002695 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002696 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002697 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002698}
2699
2700void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2701{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002702 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002703 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002704
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002705 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002706 ASSERT(framebuffer);
2707
2708 // The specification isn't clear what should be done when the framebuffer isn't complete.
2709 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002710 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002711}
2712
2713void Context::invalidateFramebuffer(GLenum target,
2714 GLsizei numAttachments,
2715 const GLenum *attachments)
2716{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002717 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002718 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002719
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002720 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002721 ASSERT(framebuffer);
2722
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002723 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002724 {
Jamie Madill437fa652016-05-03 15:13:24 -04002725 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002726 }
Jamie Madill437fa652016-05-03 15:13:24 -04002727
2728 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002729}
2730
2731void Context::invalidateSubFramebuffer(GLenum target,
2732 GLsizei numAttachments,
2733 const GLenum *attachments,
2734 GLint x,
2735 GLint y,
2736 GLsizei width,
2737 GLsizei height)
2738{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002741
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002742 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002743 ASSERT(framebuffer);
2744
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 {
Jamie Madill437fa652016-05-03 15:13:24 -04002747 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002748 }
Jamie Madill437fa652016-05-03 15:13:24 -04002749
2750 Rectangle area(x, y, width, height);
2751 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002752}
2753
Jamie Madill73a84962016-02-12 09:27:23 -05002754void Context::texImage2D(GLenum target,
2755 GLint level,
2756 GLint internalformat,
2757 GLsizei width,
2758 GLsizei height,
2759 GLint border,
2760 GLenum format,
2761 GLenum type,
2762 const GLvoid *pixels)
2763{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002764 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002765
2766 Extents size(width, height, 1);
2767 Texture *texture =
2768 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002769 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002770 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002771}
2772
2773void Context::texImage3D(GLenum target,
2774 GLint level,
2775 GLint internalformat,
2776 GLsizei width,
2777 GLsizei height,
2778 GLsizei depth,
2779 GLint border,
2780 GLenum format,
2781 GLenum type,
2782 const GLvoid *pixels)
2783{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002784 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002785
2786 Extents size(width, height, depth);
2787 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002789 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002790}
2791
2792void Context::texSubImage2D(GLenum target,
2793 GLint level,
2794 GLint xoffset,
2795 GLint yoffset,
2796 GLsizei width,
2797 GLsizei height,
2798 GLenum format,
2799 GLenum type,
2800 const GLvoid *pixels)
2801{
2802 // Zero sized uploads are valid but no-ops
2803 if (width == 0 || height == 0)
2804 {
2805 return;
2806 }
2807
Jamie Madillad9f24e2016-02-12 09:27:24 -05002808 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002809
2810 Box area(xoffset, yoffset, 0, width, height, 1);
2811 Texture *texture =
2812 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002814 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002815}
2816
2817void Context::texSubImage3D(GLenum target,
2818 GLint level,
2819 GLint xoffset,
2820 GLint yoffset,
2821 GLint zoffset,
2822 GLsizei width,
2823 GLsizei height,
2824 GLsizei depth,
2825 GLenum format,
2826 GLenum type,
2827 const GLvoid *pixels)
2828{
2829 // Zero sized uploads are valid but no-ops
2830 if (width == 0 || height == 0 || depth == 0)
2831 {
2832 return;
2833 }
2834
Jamie Madillad9f24e2016-02-12 09:27:24 -05002835 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002836
2837 Box area(xoffset, yoffset, zoffset, width, height, depth);
2838 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002840 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002841}
2842
2843void Context::compressedTexImage2D(GLenum target,
2844 GLint level,
2845 GLenum internalformat,
2846 GLsizei width,
2847 GLsizei height,
2848 GLint border,
2849 GLsizei imageSize,
2850 const GLvoid *data)
2851{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002852 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002853
2854 Extents size(width, height, 1);
2855 Texture *texture =
2856 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002857 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2858 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002859 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002860}
2861
2862void Context::compressedTexImage3D(GLenum target,
2863 GLint level,
2864 GLenum internalformat,
2865 GLsizei width,
2866 GLsizei height,
2867 GLsizei depth,
2868 GLint border,
2869 GLsizei imageSize,
2870 const GLvoid *data)
2871{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002872 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002873
2874 Extents size(width, height, depth);
2875 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002876 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2877 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002878 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002879}
2880
2881void Context::compressedTexSubImage2D(GLenum target,
2882 GLint level,
2883 GLint xoffset,
2884 GLint yoffset,
2885 GLsizei width,
2886 GLsizei height,
2887 GLenum format,
2888 GLsizei imageSize,
2889 const GLvoid *data)
2890{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002891 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002892
2893 Box area(xoffset, yoffset, 0, width, height, 1);
2894 Texture *texture =
2895 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002896 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2897 format, imageSize,
2898 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002899}
2900
2901void Context::compressedTexSubImage3D(GLenum target,
2902 GLint level,
2903 GLint xoffset,
2904 GLint yoffset,
2905 GLint zoffset,
2906 GLsizei width,
2907 GLsizei height,
2908 GLsizei depth,
2909 GLenum format,
2910 GLsizei imageSize,
2911 const GLvoid *data)
2912{
2913 // Zero sized uploads are valid but no-ops
2914 if (width == 0 || height == 0)
2915 {
2916 return;
2917 }
2918
Jamie Madillad9f24e2016-02-12 09:27:24 -05002919 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002920
2921 Box area(xoffset, yoffset, zoffset, width, height, depth);
2922 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2924 format, imageSize,
2925 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002926}
2927
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002928void Context::generateMipmap(GLenum target)
2929{
2930 Texture *texture = getTargetTexture(target);
2931 handleError(texture->generateMipmap());
2932}
2933
Geoff Langc287ea62016-09-16 14:46:51 -04002934GLboolean Context::enableExtension(const char *name)
2935{
2936 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2937 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2938 const auto &extension = extensionInfos.at(name);
2939 ASSERT(extension.Enableable);
2940
2941 if (mExtensions.*(extension.ExtensionsMember))
2942 {
2943 // Extension already enabled
2944 return GL_TRUE;
2945 }
2946
2947 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2948 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2949 {
2950 // Underlying implementation does not support this valid extension
2951 return GL_FALSE;
2952 }
2953
2954 mExtensions.*(extension.ExtensionsMember) = true;
2955 updateCaps();
2956 initExtensionStrings();
2957 return GL_TRUE;
2958}
2959
Geoff Lang97073d12016-04-20 10:42:34 -07002960void Context::copyTextureCHROMIUM(GLuint sourceId,
2961 GLuint destId,
2962 GLint internalFormat,
2963 GLenum destType,
2964 GLboolean unpackFlipY,
2965 GLboolean unpackPremultiplyAlpha,
2966 GLboolean unpackUnmultiplyAlpha)
2967{
2968 syncStateForTexImage();
2969
2970 gl::Texture *sourceTexture = getTexture(sourceId);
2971 gl::Texture *destTexture = getTexture(destId);
2972 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2973 unpackPremultiplyAlpha == GL_TRUE,
2974 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2975}
2976
2977void Context::copySubTextureCHROMIUM(GLuint sourceId,
2978 GLuint destId,
2979 GLint xoffset,
2980 GLint yoffset,
2981 GLint x,
2982 GLint y,
2983 GLsizei width,
2984 GLsizei height,
2985 GLboolean unpackFlipY,
2986 GLboolean unpackPremultiplyAlpha,
2987 GLboolean unpackUnmultiplyAlpha)
2988{
2989 // Zero sized copies are valid but no-ops
2990 if (width == 0 || height == 0)
2991 {
2992 return;
2993 }
2994
2995 syncStateForTexImage();
2996
2997 gl::Texture *sourceTexture = getTexture(sourceId);
2998 gl::Texture *destTexture = getTexture(destId);
2999 Offset offset(xoffset, yoffset, 0);
3000 Rectangle area(x, y, width, height);
3001 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3002 unpackPremultiplyAlpha == GL_TRUE,
3003 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3004}
3005
Geoff Lang47110bf2016-04-20 11:13:22 -07003006void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3007{
3008 syncStateForTexImage();
3009
3010 gl::Texture *sourceTexture = getTexture(sourceId);
3011 gl::Texture *destTexture = getTexture(destId);
3012 handleError(destTexture->copyCompressedTexture(sourceTexture));
3013}
3014
Geoff Lang496c02d2016-10-20 11:38:11 -07003015void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003016{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003017 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003018 ASSERT(buffer);
3019
Geoff Lang496c02d2016-10-20 11:38:11 -07003020 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003021}
3022
3023GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3024{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003025 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003026 ASSERT(buffer);
3027
3028 Error error = buffer->map(access);
3029 if (error.isError())
3030 {
Jamie Madill437fa652016-05-03 15:13:24 -04003031 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003032 return nullptr;
3033 }
3034
3035 return buffer->getMapPointer();
3036}
3037
3038GLboolean Context::unmapBuffer(GLenum target)
3039{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003041 ASSERT(buffer);
3042
3043 GLboolean result;
3044 Error error = buffer->unmap(&result);
3045 if (error.isError())
3046 {
Jamie Madill437fa652016-05-03 15:13:24 -04003047 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003048 return GL_FALSE;
3049 }
3050
3051 return result;
3052}
3053
3054GLvoid *Context::mapBufferRange(GLenum target,
3055 GLintptr offset,
3056 GLsizeiptr length,
3057 GLbitfield access)
3058{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003059 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003060 ASSERT(buffer);
3061
3062 Error error = buffer->mapRange(offset, length, access);
3063 if (error.isError())
3064 {
Jamie Madill437fa652016-05-03 15:13:24 -04003065 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003066 return nullptr;
3067 }
3068
3069 return buffer->getMapPointer();
3070}
3071
3072void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3073{
3074 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3075}
3076
Jamie Madillad9f24e2016-02-12 09:27:24 -05003077void Context::syncStateForReadPixels()
3078{
3079 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3080}
3081
3082void Context::syncStateForTexImage()
3083{
3084 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3085}
3086
3087void Context::syncStateForClear()
3088{
3089 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3090}
3091
3092void Context::syncStateForBlit()
3093{
3094 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3095}
3096
Jamie Madillc20ab272016-06-09 07:20:46 -07003097void Context::activeTexture(GLenum texture)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003100}
3101
3102void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3103{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003104 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003105}
3106
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003107void Context::blendEquation(GLenum mode)
3108{
3109 mGLState.setBlendEquation(mode, mode);
3110}
3111
Jamie Madillc20ab272016-06-09 07:20:46 -07003112void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003115}
3116
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003117void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3118{
3119 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3120}
3121
Jamie Madillc20ab272016-06-09 07:20:46 -07003122void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3123{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003125}
3126
3127void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3128{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003129 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003130}
3131
3132void Context::clearDepthf(GLclampf depth)
3133{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003135}
3136
3137void Context::clearStencil(GLint s)
3138{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003139 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003140}
3141
3142void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3143{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003144 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003145}
3146
3147void Context::cullFace(GLenum mode)
3148{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003149 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003150}
3151
3152void Context::depthFunc(GLenum func)
3153{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003154 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003155}
3156
3157void Context::depthMask(GLboolean flag)
3158{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003159 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003160}
3161
3162void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3163{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003164 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003165}
3166
3167void Context::disable(GLenum cap)
3168{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003169 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003170}
3171
3172void Context::disableVertexAttribArray(GLuint index)
3173{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003174 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003175}
3176
3177void Context::enable(GLenum cap)
3178{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003180}
3181
3182void Context::enableVertexAttribArray(GLuint index)
3183{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003184 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003185}
3186
3187void Context::frontFace(GLenum mode)
3188{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003190}
3191
3192void Context::hint(GLenum target, GLenum mode)
3193{
3194 switch (target)
3195 {
3196 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198 break;
3199
3200 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003201 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003202 break;
3203
3204 default:
3205 UNREACHABLE();
3206 return;
3207 }
3208}
3209
3210void Context::lineWidth(GLfloat width)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
3215void Context::pixelStorei(GLenum pname, GLint param)
3216{
3217 switch (pname)
3218 {
3219 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003220 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003221 break;
3222
3223 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225 break;
3226
3227 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003228 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003229 break;
3230
3231 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003232 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003233 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003234 break;
3235
3236 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003237 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003238 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003239 break;
3240
3241 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003242 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003243 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003244 break;
3245
3246 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003247 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003248 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003249 break;
3250
3251 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003252 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003253 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003254 break;
3255
3256 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003257 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259 break;
3260
3261 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003262 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003263 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003264 break;
3265
3266 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003267 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003268 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003269 break;
3270
3271 default:
3272 UNREACHABLE();
3273 return;
3274 }
3275}
3276
3277void Context::polygonOffset(GLfloat factor, GLfloat units)
3278{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280}
3281
3282void Context::sampleCoverage(GLclampf value, GLboolean invert)
3283{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003284 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003285}
3286
3287void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3288{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003290}
3291
3292void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3293{
3294 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3295 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 }
3298
3299 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3300 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302 }
3303}
3304
3305void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3306{
3307 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3308 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003309 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003310 }
3311
3312 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3313 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315 }
3316}
3317
3318void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3319{
3320 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3321 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323 }
3324
3325 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3326 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328 }
3329}
3330
3331void Context::vertexAttrib1f(GLuint index, GLfloat x)
3332{
3333 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335}
3336
3337void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3338{
3339 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003341}
3342
3343void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3344{
3345 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3350{
3351 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353}
3354
3355void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3356{
3357 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359}
3360
3361void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3362{
3363 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365}
3366
3367void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3368{
3369 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003370 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003371}
3372
3373void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3374{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::vertexAttribPointer(GLuint index,
3379 GLint size,
3380 GLenum type,
3381 GLboolean normalized,
3382 GLsizei stride,
3383 const GLvoid *ptr)
3384{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003385 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3386 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387}
3388
3389void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3390{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003392}
3393
3394void Context::vertexAttribIPointer(GLuint index,
3395 GLint size,
3396 GLenum type,
3397 GLsizei stride,
3398 const GLvoid *pointer)
3399{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003400 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3401 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402}
3403
3404void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3405{
3406 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3411{
3412 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3417{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419}
3420
3421void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3422{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424}
3425
3426void Context::debugMessageControl(GLenum source,
3427 GLenum type,
3428 GLenum severity,
3429 GLsizei count,
3430 const GLuint *ids,
3431 GLboolean enabled)
3432{
3433 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3435 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::debugMessageInsert(GLenum source,
3439 GLenum type,
3440 GLuint id,
3441 GLenum severity,
3442 GLsizei length,
3443 const GLchar *buf)
3444{
3445 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
3449void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3450{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454GLuint Context::getDebugMessageLog(GLuint count,
3455 GLsizei bufSize,
3456 GLenum *sources,
3457 GLenum *types,
3458 GLuint *ids,
3459 GLenum *severities,
3460 GLsizei *lengths,
3461 GLchar *messageLog)
3462{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003463 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3464 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003465}
3466
3467void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3468{
3469 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003470 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003471}
3472
3473void Context::popDebugGroup()
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
Jamie Madill29639852016-09-02 15:00:09 -04003478void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3479{
3480 Buffer *buffer = mGLState.getTargetBuffer(target);
3481 ASSERT(buffer);
3482 handleError(buffer->bufferData(target, data, size, usage));
3483}
3484
3485void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3486{
3487 if (data == nullptr)
3488 {
3489 return;
3490 }
3491
3492 Buffer *buffer = mGLState.getTargetBuffer(target);
3493 ASSERT(buffer);
3494 handleError(buffer->bufferSubData(target, data, size, offset));
3495}
3496
Jamie Madillef300b12016-10-07 15:12:09 -04003497void Context::attachShader(GLuint program, GLuint shader)
3498{
3499 auto programObject = mResourceManager->getProgram(program);
3500 auto shaderObject = mResourceManager->getShader(shader);
3501 ASSERT(programObject && shaderObject);
3502 programObject->attachShader(shaderObject);
3503}
3504
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003505const Workarounds &Context::getWorkarounds() const
3506{
3507 return mWorkarounds;
3508}
3509
Jamie Madillb0817d12016-11-01 15:48:31 -04003510void Context::copyBufferSubData(GLenum readTarget,
3511 GLenum writeTarget,
3512 GLintptr readOffset,
3513 GLintptr writeOffset,
3514 GLsizeiptr size)
3515{
3516 // if size is zero, the copy is a successful no-op
3517 if (size == 0)
3518 {
3519 return;
3520 }
3521
3522 // TODO(jmadill): cache these.
3523 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3524 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3525
3526 handleError(writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size));
3527}
3528
Jamie Madill01a80ee2016-11-07 12:06:18 -05003529void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3530{
3531 Program *programObject = getProgram(program);
3532 // TODO(jmadill): Re-use this from the validation if possible.
3533 ASSERT(programObject);
3534 programObject->bindAttributeLocation(index, name);
3535}
3536
3537void Context::bindBuffer(GLenum target, GLuint buffer)
3538{
3539 switch (target)
3540 {
3541 case GL_ARRAY_BUFFER:
3542 bindArrayBuffer(buffer);
3543 break;
3544 case GL_ELEMENT_ARRAY_BUFFER:
3545 bindElementArrayBuffer(buffer);
3546 break;
3547 case GL_COPY_READ_BUFFER:
3548 bindCopyReadBuffer(buffer);
3549 break;
3550 case GL_COPY_WRITE_BUFFER:
3551 bindCopyWriteBuffer(buffer);
3552 break;
3553 case GL_PIXEL_PACK_BUFFER:
3554 bindPixelPackBuffer(buffer);
3555 break;
3556 case GL_PIXEL_UNPACK_BUFFER:
3557 bindPixelUnpackBuffer(buffer);
3558 break;
3559 case GL_UNIFORM_BUFFER:
3560 bindGenericUniformBuffer(buffer);
3561 break;
3562 case GL_TRANSFORM_FEEDBACK_BUFFER:
3563 bindGenericTransformFeedbackBuffer(buffer);
3564 break;
3565
3566 default:
3567 UNREACHABLE();
3568 break;
3569 }
3570}
3571
3572void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3573{
3574 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3575 {
3576 bindReadFramebuffer(framebuffer);
3577 }
3578
3579 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3580 {
3581 bindDrawFramebuffer(framebuffer);
3582 }
3583}
3584
3585void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3586{
3587 ASSERT(target == GL_RENDERBUFFER);
3588 Renderbuffer *object =
3589 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
3590 mGLState.setRenderbufferBinding(object);
3591}
3592
Jamie Madillc29968b2016-01-20 11:17:23 -05003593} // namespace gl