blob: 235a3a5ff517125676456ce8f0306d712b829d60 [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"
Jamie Madill437fa652016-05-03 15:13:24 -040038#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040039#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000041
Geoff Langf6db0982015-08-25 13:04:00 -040042namespace
43{
44
Ian Ewell3ffd78b2016-01-22 16:09:42 -050045template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030046std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
47 GLsizei numPaths,
48 const void *paths,
49 GLuint pathBase)
50{
51 std::vector<gl::Path *> ret;
52 ret.reserve(numPaths);
53
54 const auto *nameArray = static_cast<const T *>(paths);
55
56 for (GLsizei i = 0; i < numPaths; ++i)
57 {
58 const GLuint pathName = nameArray[i] + pathBase;
59
60 ret.push_back(resourceManager.getPath(pathName));
61 }
62
63 return ret;
64}
65
66std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
67 GLsizei numPaths,
68 GLenum pathNameType,
69 const void *paths,
70 GLuint pathBase)
71{
72 switch (pathNameType)
73 {
74 case GL_UNSIGNED_BYTE:
75 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
76
77 case GL_BYTE:
78 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_UNSIGNED_SHORT:
81 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_SHORT:
84 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_UNSIGNED_INT:
87 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_INT:
90 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
91 }
92
93 UNREACHABLE();
94 return std::vector<gl::Path *>();
95}
96
97template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050098gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
99{
100 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
101 ASSERT(queryObject != nullptr);
102
103 switch (pname)
104 {
105 case GL_QUERY_RESULT_EXT:
106 return queryObject->getResult(params);
107 case GL_QUERY_RESULT_AVAILABLE_EXT:
108 {
109 bool available;
110 gl::Error error = queryObject->isResultAvailable(&available);
111 if (!error.isError())
112 {
113 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
114 }
115 return error;
116 }
117 default:
118 UNREACHABLE();
119 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
120 }
121}
122
Geoff Langf6db0982015-08-25 13:04:00 -0400123void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
124{
Geoff Lang1a683462015-09-29 15:09:59 -0400125 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400126 {
127 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
128 tfBufferIndex++)
129 {
130 const OffsetBindingPointer<gl::Buffer> &buffer =
131 transformFeedback->getIndexedBuffer(tfBufferIndex);
132 if (buffer.get() != nullptr)
133 {
134 buffer->onTransformFeedback();
135 }
136 }
137 }
138}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139
140// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300141EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400143 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144}
145
Martin Radev1be913c2016-07-11 17:59:16 +0300146EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
147{
148 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
149}
150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151GLenum GetResetStrategy(const egl::AttributeMap &attribs)
152{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400153 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
154 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 switch (attrib)
156 {
157 case EGL_NO_RESET_NOTIFICATION:
158 return GL_NO_RESET_NOTIFICATION_EXT;
159 case EGL_LOSE_CONTEXT_ON_RESET:
160 return GL_LOSE_CONTEXT_ON_RESET_EXT;
161 default:
162 UNREACHABLE();
163 return GL_NONE;
164 }
165}
166
167bool GetRobustAccess(const egl::AttributeMap &attribs)
168{
169 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
170}
171
172bool GetDebug(const egl::AttributeMap &attribs)
173{
174 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
175}
176
177bool GetNoError(const egl::AttributeMap &attribs)
178{
179 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
180}
181
Geoff Langc287ea62016-09-16 14:46:51 -0400182bool GetWebGLContext(const egl::AttributeMap &attribs)
183{
184 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
185}
186
Geoff Langf41a7152016-09-19 15:11:17 -0400187bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
188{
189 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
190}
191
Martin Radev9d901792016-07-15 15:58:58 +0300192std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
193{
194 std::string labelName;
195 if (label != nullptr)
196 {
197 size_t labelLength = length < 0 ? strlen(label) : length;
198 labelName = std::string(label, labelLength);
199 }
200 return labelName;
201}
202
203void GetObjectLabelBase(const std::string &objectLabel,
204 GLsizei bufSize,
205 GLsizei *length,
206 GLchar *label)
207{
208 size_t writeLength = objectLabel.length();
209 if (label != nullptr && bufSize > 0)
210 {
211 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
212 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
213 label[writeLength] = '\0';
214 }
215
216 if (length != nullptr)
217 {
218 *length = static_cast<GLsizei>(writeLength);
219 }
220}
221
Geoff Langf6db0982015-08-25 13:04:00 -0400222} // anonymous namespace
223
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000224namespace gl
225{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000226
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400227Context::Context(rx::EGLImplFactory *implFactory,
228 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400229 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500230 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300231
232 : ValidationContext(GetClientMajorVersion(attribs),
233 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700234 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500235 mCaps,
236 mTextureCaps,
237 mExtensions,
238 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500239 mLimitations,
240 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700241 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500242 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300243 mClientMajorVersion(GetClientMajorVersion(attribs)),
244 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400245 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500246 mClientType(EGL_OPENGL_ES_API),
247 mHasBeenCurrent(false),
248 mContextLost(false),
249 mResetStatus(GL_NO_ERROR),
250 mResetStrategy(GetResetStrategy(attribs)),
251 mRobustAccess(GetRobustAccess(attribs)),
252 mCurrentSurface(nullptr),
253 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000254{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500255 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256
Geoff Langc287ea62016-09-16 14:46:51 -0400257 initCaps(GetWebGLContext(attribs));
Geoff Langc0b9ef42014-07-02 10:02:37 -0400258
Geoff Langf41a7152016-09-19 15:11:17 -0400259 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs),
260 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100261
Shannon Woods53a94a82014-06-24 15:20:36 -0400262 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400263
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400264 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000265 {
266 mResourceManager = shareContext->mResourceManager;
267 mResourceManager->addRef();
268 }
269 else
270 {
Jamie Madill901b3792016-05-26 09:20:40 -0400271 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000272 }
273
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700274 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400275
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 // [OpenGL ES 2.0.24] section 3.7 page 83:
277 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
278 // and cube map texture state vectors respectively associated with them.
279 // In order that access to these initial textures not be lost, they are treated as texture
280 // objects all of whose names are 0.
281
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400282 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500283 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400285 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500286 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400287
Martin Radev1be913c2016-07-11 17:59:16 +0300288 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400289 {
290 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400291 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500292 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400293
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400294 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500295 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400296 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297
Ian Ewellbda75592016-04-18 17:25:54 -0400298 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
299 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400300 Texture *zeroTextureExternal =
301 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400302 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
303 }
304
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700305 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500306
Jamie Madill57a89722013-07-02 11:57:03 -0400307 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000308 bindArrayBuffer(0);
309 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400310
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311 bindRenderbuffer(0);
312
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000313 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400314 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000315 {
316 bindIndexedUniformBuffer(0, i, 0, -1);
317 }
318
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000319 bindCopyReadBuffer(0);
320 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000321 bindPixelPackBuffer(0);
322 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000323
Martin Radev1be913c2016-07-11 17:59:16 +0300324 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400325 {
326 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
327 // In the initial state, a default transform feedback object is bound and treated as
328 // a transform feedback object with a name of zero. That object is bound any time
329 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400330 bindTransformFeedback(0);
331 }
Geoff Langc8058452014-02-03 12:04:11 -0500332
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700333 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500334
335 // Initialize dirty bit masks
336 // TODO(jmadill): additional ES3 state
337 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
338 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
339 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
340 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
341 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
342 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400343 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500344 // No dirty objects.
345
346 // Readpixels uses the pack state and read FBO
347 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
348 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
349 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
350 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
351 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400352 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500353 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
354
355 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
356 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
357 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
358 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
359 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
360 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
361 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
362 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
363 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
364 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
365 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
366 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
367
368 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
369 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
370 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
371 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400372
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400373 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000374}
375
376Context::~Context()
377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700378 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000379
Corentin Wallez37c39792015-08-20 14:19:46 -0400380 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000381 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400382 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400383 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400384 {
385 SafeDelete(framebuffer.second);
386 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387 }
388
Corentin Wallez80b24112015-08-25 16:41:57 -0400389 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400391 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000392 }
393
Corentin Wallez80b24112015-08-25 16:41:57 -0400394 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400396 if (query.second != nullptr)
397 {
398 query.second->release();
399 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400 }
401
Corentin Wallez80b24112015-08-25 16:41:57 -0400402 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400403 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400404 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400405 }
406
Corentin Wallez80b24112015-08-25 16:41:57 -0400407 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500408 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500409 if (transformFeedback.second != nullptr)
410 {
411 transformFeedback.second->release();
412 }
Geoff Langc8058452014-02-03 12:04:11 -0500413 }
414
Jamie Madilldedd7b92014-11-05 16:30:36 -0500415 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400416 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500417 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400418 }
419 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420
Corentin Wallez51706ea2015-08-07 14:39:22 -0400421 if (mCurrentSurface != nullptr)
422 {
423 releaseSurface();
424 }
425
Jamie Madill1e9ae072014-11-06 15:27:21 -0500426 if (mResourceManager)
427 {
428 mResourceManager->release();
429 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500430
431 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000432}
433
daniel@transgaming.comad629872012-11-28 19:32:06 +0000434void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435{
Jamie Madill77a72f62015-04-14 11:18:32 -0400436 ASSERT(surface != nullptr);
437
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438 if (!mHasBeenCurrent)
439 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000440 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400441 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000442
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700443 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
444 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000445
446 mHasBeenCurrent = true;
447 }
448
Jamie Madill1b94d432015-08-07 13:23:23 -0400449 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700450 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400451
Corentin Wallez51706ea2015-08-07 14:39:22 -0400452 if (mCurrentSurface)
453 {
454 releaseSurface();
455 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000456 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400457 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000458
Corentin Wallez37c39792015-08-20 14:19:46 -0400459 // Update default framebuffer, the binding of the previous default
460 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400461 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400462 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700463 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400464 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400466 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700467 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 }
471 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400472 }
Ian Ewell292f0052016-02-04 10:37:32 -0500473
474 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700475 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476}
477
Jamie Madill77a72f62015-04-14 11:18:32 -0400478void Context::releaseSurface()
479{
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 ASSERT(mCurrentSurface != nullptr);
481
482 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400483 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400484 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700485 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700487 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400488 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700489 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 }
493 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400494 }
495
Corentin Wallez51706ea2015-08-07 14:39:22 -0400496 mCurrentSurface->setIsCurrent(false);
497 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400498}
499
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000500GLuint Context::createBuffer()
501{
502 return mResourceManager->createBuffer();
503}
504
505GLuint Context::createProgram()
506{
Jamie Madill901b3792016-05-26 09:20:40 -0400507 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000508}
509
510GLuint Context::createShader(GLenum type)
511{
Jamie Madill901b3792016-05-26 09:20:40 -0400512 return mResourceManager->createShader(mImplementation.get(),
513 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000514}
515
516GLuint Context::createTexture()
517{
518 return mResourceManager->createTexture();
519}
520
521GLuint Context::createRenderbuffer()
522{
523 return mResourceManager->createRenderbuffer();
524}
525
Geoff Lang882033e2014-09-30 11:26:07 -0400526GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400527{
Jamie Madill901b3792016-05-26 09:20:40 -0400528 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400529
Cooper Partind8e62a32015-01-29 15:21:25 -0800530 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400531}
532
Sami Väisänene45e53b2016-05-25 10:36:04 +0300533GLuint Context::createPaths(GLsizei range)
534{
535 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
536 if (resultOrError.isError())
537 {
538 handleError(resultOrError.getError());
539 return 0;
540 }
541 return resultOrError.getResult();
542}
543
Jamie Madill57a89722013-07-02 11:57:03 -0400544GLuint Context::createVertexArray()
545{
Geoff Lang36167ab2015-12-07 10:27:14 -0500546 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
547 mVertexArrayMap[vertexArray] = nullptr;
548 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400549}
550
Jamie Madilldc356042013-07-19 16:36:57 -0400551GLuint Context::createSampler()
552{
553 return mResourceManager->createSampler();
554}
555
Geoff Langc8058452014-02-03 12:04:11 -0500556GLuint Context::createTransformFeedback()
557{
Geoff Lang36167ab2015-12-07 10:27:14 -0500558 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
559 mTransformFeedbackMap[transformFeedback] = nullptr;
560 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500561}
562
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563// Returns an unused framebuffer name
564GLuint Context::createFramebuffer()
565{
566 GLuint handle = mFramebufferHandleAllocator.allocate();
567
568 mFramebufferMap[handle] = NULL;
569
570 return handle;
571}
572
Jamie Madill33dc8432013-07-26 11:55:05 -0400573GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574{
Jamie Madill33dc8432013-07-26 11:55:05 -0400575 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400577 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578
579 return handle;
580}
581
582// Returns an unused query name
583GLuint Context::createQuery()
584{
585 GLuint handle = mQueryHandleAllocator.allocate();
586
587 mQueryMap[handle] = NULL;
588
589 return handle;
590}
591
592void Context::deleteBuffer(GLuint buffer)
593{
594 if (mResourceManager->getBuffer(buffer))
595 {
596 detachBuffer(buffer);
597 }
Jamie Madill893ab082014-05-16 16:56:10 -0400598
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 mResourceManager->deleteBuffer(buffer);
600}
601
602void Context::deleteShader(GLuint shader)
603{
604 mResourceManager->deleteShader(shader);
605}
606
607void Context::deleteProgram(GLuint program)
608{
609 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000610}
611
612void Context::deleteTexture(GLuint texture)
613{
614 if (mResourceManager->getTexture(texture))
615 {
616 detachTexture(texture);
617 }
618
619 mResourceManager->deleteTexture(texture);
620}
621
622void Context::deleteRenderbuffer(GLuint renderbuffer)
623{
624 if (mResourceManager->getRenderbuffer(renderbuffer))
625 {
626 detachRenderbuffer(renderbuffer);
627 }
Jamie Madill893ab082014-05-16 16:56:10 -0400628
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 mResourceManager->deleteRenderbuffer(renderbuffer);
630}
631
Jamie Madillcd055f82013-07-26 11:55:15 -0400632void Context::deleteFenceSync(GLsync fenceSync)
633{
634 // The spec specifies the underlying Fence object is not deleted until all current
635 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
636 // and since our API is currently designed for being called from a single thread, we can delete
637 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700638 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400639}
640
Sami Väisänene45e53b2016-05-25 10:36:04 +0300641void Context::deletePaths(GLuint first, GLsizei range)
642{
643 mResourceManager->deletePaths(first, range);
644}
645
646bool Context::hasPathData(GLuint path) const
647{
648 const auto *pathObj = mResourceManager->getPath(path);
649 if (pathObj == nullptr)
650 return false;
651
652 return pathObj->hasPathData();
653}
654
655bool Context::hasPath(GLuint path) const
656{
657 return mResourceManager->hasPath(path);
658}
659
660void Context::setPathCommands(GLuint path,
661 GLsizei numCommands,
662 const GLubyte *commands,
663 GLsizei numCoords,
664 GLenum coordType,
665 const void *coords)
666{
667 auto *pathObject = mResourceManager->getPath(path);
668
669 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
670}
671
672void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
673{
674 auto *pathObj = mResourceManager->getPath(path);
675
676 switch (pname)
677 {
678 case GL_PATH_STROKE_WIDTH_CHROMIUM:
679 pathObj->setStrokeWidth(value);
680 break;
681 case GL_PATH_END_CAPS_CHROMIUM:
682 pathObj->setEndCaps(static_cast<GLenum>(value));
683 break;
684 case GL_PATH_JOIN_STYLE_CHROMIUM:
685 pathObj->setJoinStyle(static_cast<GLenum>(value));
686 break;
687 case GL_PATH_MITER_LIMIT_CHROMIUM:
688 pathObj->setMiterLimit(value);
689 break;
690 case GL_PATH_STROKE_BOUND_CHROMIUM:
691 pathObj->setStrokeBound(value);
692 break;
693 default:
694 UNREACHABLE();
695 break;
696 }
697}
698
699void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
700{
701 const auto *pathObj = mResourceManager->getPath(path);
702
703 switch (pname)
704 {
705 case GL_PATH_STROKE_WIDTH_CHROMIUM:
706 *value = pathObj->getStrokeWidth();
707 break;
708 case GL_PATH_END_CAPS_CHROMIUM:
709 *value = static_cast<GLfloat>(pathObj->getEndCaps());
710 break;
711 case GL_PATH_JOIN_STYLE_CHROMIUM:
712 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
713 break;
714 case GL_PATH_MITER_LIMIT_CHROMIUM:
715 *value = pathObj->getMiterLimit();
716 break;
717 case GL_PATH_STROKE_BOUND_CHROMIUM:
718 *value = pathObj->getStrokeBound();
719 break;
720 default:
721 UNREACHABLE();
722 break;
723 }
724}
725
726void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
727{
728 mGLState.setPathStencilFunc(func, ref, mask);
729}
730
Jamie Madill57a89722013-07-02 11:57:03 -0400731void Context::deleteVertexArray(GLuint vertexArray)
732{
Geoff Lang36167ab2015-12-07 10:27:14 -0500733 auto iter = mVertexArrayMap.find(vertexArray);
734 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000735 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500736 VertexArray *vertexArrayObject = iter->second;
737 if (vertexArrayObject != nullptr)
738 {
739 detachVertexArray(vertexArray);
740 delete vertexArrayObject;
741 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000742
Geoff Lang36167ab2015-12-07 10:27:14 -0500743 mVertexArrayMap.erase(iter);
744 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400745 }
746}
747
Jamie Madilldc356042013-07-19 16:36:57 -0400748void Context::deleteSampler(GLuint sampler)
749{
750 if (mResourceManager->getSampler(sampler))
751 {
752 detachSampler(sampler);
753 }
754
755 mResourceManager->deleteSampler(sampler);
756}
757
Geoff Langc8058452014-02-03 12:04:11 -0500758void Context::deleteTransformFeedback(GLuint transformFeedback)
759{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500760 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500761 if (iter != mTransformFeedbackMap.end())
762 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500763 TransformFeedback *transformFeedbackObject = iter->second;
764 if (transformFeedbackObject != nullptr)
765 {
766 detachTransformFeedback(transformFeedback);
767 transformFeedbackObject->release();
768 }
769
Geoff Lang50b3fe82015-12-08 14:49:12 +0000770 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500771 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500772 }
773}
774
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000775void Context::deleteFramebuffer(GLuint framebuffer)
776{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500777 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000778
779 if (framebufferObject != mFramebufferMap.end())
780 {
781 detachFramebuffer(framebuffer);
782
783 mFramebufferHandleAllocator.release(framebufferObject->first);
784 delete framebufferObject->second;
785 mFramebufferMap.erase(framebufferObject);
786 }
787}
788
Jamie Madill33dc8432013-07-26 11:55:05 -0400789void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000790{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500791 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792
Jamie Madill33dc8432013-07-26 11:55:05 -0400793 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400795 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400797 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798 }
799}
800
801void Context::deleteQuery(GLuint query)
802{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500803 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804 if (queryObject != mQueryMap.end())
805 {
806 mQueryHandleAllocator.release(queryObject->first);
807 if (queryObject->second)
808 {
809 queryObject->second->release();
810 }
811 mQueryMap.erase(queryObject);
812 }
813}
814
Geoff Lang70d0f492015-12-10 17:45:46 -0500815Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816{
817 return mResourceManager->getBuffer(handle);
818}
819
Jamie Madill570f7c82014-07-03 10:38:54 -0400820Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821{
822 return mResourceManager->getTexture(handle);
823}
824
Geoff Lang70d0f492015-12-10 17:45:46 -0500825Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826{
827 return mResourceManager->getRenderbuffer(handle);
828}
829
Jamie Madillcd055f82013-07-26 11:55:15 -0400830FenceSync *Context::getFenceSync(GLsync handle) const
831{
Minmin Gong794e0002015-04-07 18:31:54 -0700832 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400833}
834
Jamie Madill57a89722013-07-02 11:57:03 -0400835VertexArray *Context::getVertexArray(GLuint handle) const
836{
837 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500838 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400839}
840
Jamie Madilldc356042013-07-19 16:36:57 -0400841Sampler *Context::getSampler(GLuint handle) const
842{
843 return mResourceManager->getSampler(handle);
844}
845
Geoff Langc8058452014-02-03 12:04:11 -0500846TransformFeedback *Context::getTransformFeedback(GLuint handle) const
847{
Geoff Lang36167ab2015-12-07 10:27:14 -0500848 auto iter = mTransformFeedbackMap.find(handle);
849 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500850}
851
Geoff Lang70d0f492015-12-10 17:45:46 -0500852LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
853{
854 switch (identifier)
855 {
856 case GL_BUFFER:
857 return getBuffer(name);
858 case GL_SHADER:
859 return getShader(name);
860 case GL_PROGRAM:
861 return getProgram(name);
862 case GL_VERTEX_ARRAY:
863 return getVertexArray(name);
864 case GL_QUERY:
865 return getQuery(name);
866 case GL_TRANSFORM_FEEDBACK:
867 return getTransformFeedback(name);
868 case GL_SAMPLER:
869 return getSampler(name);
870 case GL_TEXTURE:
871 return getTexture(name);
872 case GL_RENDERBUFFER:
873 return getRenderbuffer(name);
874 case GL_FRAMEBUFFER:
875 return getFramebuffer(name);
876 default:
877 UNREACHABLE();
878 return nullptr;
879 }
880}
881
882LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
883{
884 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
885}
886
Martin Radev9d901792016-07-15 15:58:58 +0300887void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
888{
889 LabeledObject *object = getLabeledObject(identifier, name);
890 ASSERT(object != nullptr);
891
892 std::string labelName = GetObjectLabelFromPointer(length, label);
893 object->setLabel(labelName);
894}
895
896void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
897{
898 LabeledObject *object = getLabeledObjectFromPtr(ptr);
899 ASSERT(object != nullptr);
900
901 std::string labelName = GetObjectLabelFromPointer(length, label);
902 object->setLabel(labelName);
903}
904
905void Context::getObjectLabel(GLenum identifier,
906 GLuint name,
907 GLsizei bufSize,
908 GLsizei *length,
909 GLchar *label) const
910{
911 LabeledObject *object = getLabeledObject(identifier, name);
912 ASSERT(object != nullptr);
913
914 const std::string &objectLabel = object->getLabel();
915 GetObjectLabelBase(objectLabel, bufSize, length, label);
916}
917
918void Context::getObjectPtrLabel(const void *ptr,
919 GLsizei bufSize,
920 GLsizei *length,
921 GLchar *label) const
922{
923 LabeledObject *object = getLabeledObjectFromPtr(ptr);
924 ASSERT(object != nullptr);
925
926 const std::string &objectLabel = object->getLabel();
927 GetObjectLabelBase(objectLabel, bufSize, length, label);
928}
929
Jamie Madilldc356042013-07-19 16:36:57 -0400930bool Context::isSampler(GLuint samplerName) const
931{
932 return mResourceManager->isSampler(samplerName);
933}
934
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500935void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000936{
Jamie Madill901b3792016-05-26 09:20:40 -0400937 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700938 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000939}
940
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500941void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942{
Jamie Madill901b3792016-05-26 09:20:40 -0400943 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700944 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945}
946
Jamie Madilldedd7b92014-11-05 16:30:36 -0500947void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500949 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950
Jamie Madilldedd7b92014-11-05 16:30:36 -0500951 if (handle == 0)
952 {
953 texture = mZeroTextures[target].get();
954 }
955 else
956 {
Jamie Madill901b3792016-05-26 09:20:40 -0400957 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500958 }
959
960 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700961 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000962}
963
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500964void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000965{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500966 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700967 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968}
969
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500970void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500972 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700973 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974}
975
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500976void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977{
Jamie Madill901b3792016-05-26 09:20:40 -0400978 Renderbuffer *renderbuffer =
979 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700980 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981}
982
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500983void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400984{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500985 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400990{
Geoff Lang76b10c92014-09-05 16:28:14 -0400991 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400992 Sampler *sampler =
993 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700994 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400995}
996
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500997void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000998{
Jamie Madill901b3792016-05-26 09:20:40 -0400999 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1004 GLuint index,
1005 GLintptr offset,
1006 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001007{
Jamie Madill901b3792016-05-26 09:20:40 -04001008 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001009 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001010}
1011
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001012void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +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.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1019 GLuint index,
1020 GLintptr offset,
1021 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001022{
Jamie Madill901b3792016-05-26 09:20:40 -04001023 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001024 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001025}
1026
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001027void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +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.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindCopyWriteBuffer(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.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +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.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindPixelUnpackBuffer(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.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049}
1050
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001051void Context::useProgram(GLuint program)
1052{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001053 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001057{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001058 TransformFeedback *transformFeedback =
1059 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001060 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001061}
1062
Geoff Lang5aad9672014-09-08 11:10:42 -04001063Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001064{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001065 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001066 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001067
Geoff Lang5aad9672014-09-08 11:10:42 -04001068 // begin query
1069 Error error = queryObject->begin();
1070 if (error.isError())
1071 {
1072 return error;
1073 }
1074
1075 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001076 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077
Geoff Lang5aad9672014-09-08 11:10:42 -04001078 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079}
1080
Geoff Lang5aad9672014-09-08 11:10:42 -04001081Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001083 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001084 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085
Geoff Lang5aad9672014-09-08 11:10:42 -04001086 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087
Geoff Lang5aad9672014-09-08 11:10:42 -04001088 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001089 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001090
1091 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092}
1093
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001094Error Context::queryCounter(GLuint id, GLenum target)
1095{
1096 ASSERT(target == GL_TIMESTAMP_EXT);
1097
1098 Query *queryObject = getQuery(id, true, target);
1099 ASSERT(queryObject);
1100
1101 return queryObject->queryCounter();
1102}
1103
1104void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1105{
1106 switch (pname)
1107 {
1108 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001109 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001110 break;
1111 case GL_QUERY_COUNTER_BITS_EXT:
1112 switch (target)
1113 {
1114 case GL_TIME_ELAPSED_EXT:
1115 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1116 break;
1117 case GL_TIMESTAMP_EXT:
1118 params[0] = getExtensions().queryCounterBitsTimestamp;
1119 break;
1120 default:
1121 UNREACHABLE();
1122 params[0] = 0;
1123 break;
1124 }
1125 break;
1126 default:
1127 UNREACHABLE();
1128 return;
1129 }
1130}
1131
1132Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1133{
1134 return GetQueryObjectParameter(this, id, pname, params);
1135}
1136
1137Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1138{
1139 return GetQueryObjectParameter(this, id, pname, params);
1140}
1141
1142Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1143{
1144 return GetQueryObjectParameter(this, id, pname, params);
1145}
1146
1147Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1148{
1149 return GetQueryObjectParameter(this, id, pname, params);
1150}
1151
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001152Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001153{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001154 auto framebufferIt = mFramebufferMap.find(handle);
1155 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156}
1157
Jamie Madill33dc8432013-07-26 11:55:05 -04001158FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001160 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161
Jamie Madill33dc8432013-07-26 11:55:05 -04001162 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163 {
1164 return NULL;
1165 }
1166 else
1167 {
1168 return fence->second;
1169 }
1170}
1171
1172Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1173{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001174 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001175
1176 if (query == mQueryMap.end())
1177 {
1178 return NULL;
1179 }
1180 else
1181 {
1182 if (!query->second && create)
1183 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001184 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 query->second->addRef();
1186 }
1187 return query->second;
1188 }
1189}
1190
Geoff Lang70d0f492015-12-10 17:45:46 -05001191Query *Context::getQuery(GLuint handle) const
1192{
1193 auto iter = mQueryMap.find(handle);
1194 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1195}
1196
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001197Texture *Context::getTargetTexture(GLenum target) const
1198{
Ian Ewellbda75592016-04-18 17:25:54 -04001199 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001200 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001201}
1202
Geoff Lang76b10c92014-09-05 16:28:14 -04001203Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001205 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206}
1207
Geoff Lang492a7e42014-11-05 13:27:06 -05001208Compiler *Context::getCompiler() const
1209{
1210 return mCompiler;
1211}
1212
Jamie Madill893ab082014-05-16 16:56:10 -04001213void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214{
1215 switch (pname)
1216 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001217 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001218 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001219 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001220 mGLState.getBooleanv(pname, params);
1221 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223}
1224
Jamie Madill893ab082014-05-16 16:56:10 -04001225void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226{
Shannon Woods53a94a82014-06-24 15:20:36 -04001227 // Queries about context capabilities and maximums are answered by Context.
1228 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 switch (pname)
1230 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001231 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001232 params[0] = mCaps.minAliasedLineWidth;
1233 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 break;
1235 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001236 params[0] = mCaps.minAliasedPointSize;
1237 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001239 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001240 ASSERT(mExtensions.textureFilterAnisotropic);
1241 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001242 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001243 case GL_MAX_TEXTURE_LOD_BIAS:
1244 *params = mCaps.maxLODBias;
1245 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001246
1247 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1248 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1249 {
1250 ASSERT(mExtensions.pathRendering);
1251 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1252 memcpy(params, m, 16 * sizeof(GLfloat));
1253 }
1254 break;
1255
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001256 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001257 mGLState.getFloatv(pname, params);
1258 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260}
1261
Jamie Madill893ab082014-05-16 16:56:10 -04001262void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263{
Shannon Woods53a94a82014-06-24 15:20:36 -04001264 // Queries about context capabilities and maximums are answered by Context.
1265 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001266
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 switch (pname)
1268 {
Geoff Lang301d1612014-07-09 10:34:37 -04001269 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1270 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1271 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001272 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1273 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1274 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001275 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1276 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1277 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001278 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001279 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1280 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1281 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001282 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001283 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001284 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1285 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1286 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1287 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001288 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1289 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001290 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1291 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001292 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001293 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1294 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1295 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1296 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001297 case GL_MAJOR_VERSION:
1298 *params = mClientMajorVersion;
1299 break;
1300 case GL_MINOR_VERSION:
1301 *params = mClientMinorVersion;
1302 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001303 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1304 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001305 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1306 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1307 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001308 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1309 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1310 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001311 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001312 case GL_MAX_VIEWPORT_DIMS:
1313 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001314 params[0] = mCaps.maxViewportWidth;
1315 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 }
1317 break;
1318 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001319 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001321 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1322 *params = mResetStrategy;
1323 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001324 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001325 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001327 case GL_SHADER_BINARY_FORMATS:
1328 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1329 break;
1330 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001331 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001332 break;
1333 case GL_PROGRAM_BINARY_FORMATS:
1334 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001335 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001336 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001337 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001338 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001339
1340 // GL_KHR_debug
1341 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1342 *params = mExtensions.maxDebugMessageLength;
1343 break;
1344 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1345 *params = mExtensions.maxDebugLoggedMessages;
1346 break;
1347 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1348 *params = mExtensions.maxDebugGroupStackDepth;
1349 break;
1350 case GL_MAX_LABEL_LENGTH:
1351 *params = mExtensions.maxLabelLength;
1352 break;
1353
Ian Ewell53f59f42016-01-28 17:36:55 -05001354 // GL_EXT_disjoint_timer_query
1355 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001356 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001357 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001358 case GL_MAX_FRAMEBUFFER_WIDTH:
1359 *params = mCaps.maxFramebufferWidth;
1360 break;
1361 case GL_MAX_FRAMEBUFFER_HEIGHT:
1362 *params = mCaps.maxFramebufferHeight;
1363 break;
1364 case GL_MAX_FRAMEBUFFER_SAMPLES:
1365 *params = mCaps.maxFramebufferSamples;
1366 break;
1367 case GL_MAX_SAMPLE_MASK_WORDS:
1368 *params = mCaps.maxSampleMaskWords;
1369 break;
1370 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1371 *params = mCaps.maxColorTextureSamples;
1372 break;
1373 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1374 *params = mCaps.maxDepthTextureSamples;
1375 break;
1376 case GL_MAX_INTEGER_SAMPLES:
1377 *params = mCaps.maxIntegerSamples;
1378 break;
1379 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1380 *params = mCaps.maxVertexAttribRelativeOffset;
1381 break;
1382 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1383 *params = mCaps.maxVertexAttribBindings;
1384 break;
1385 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1386 *params = mCaps.maxVertexAttribStride;
1387 break;
1388 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1389 *params = mCaps.maxVertexAtomicCounterBuffers;
1390 break;
1391 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1392 *params = mCaps.maxVertexAtomicCounters;
1393 break;
1394 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1395 *params = mCaps.maxVertexImageUniforms;
1396 break;
1397 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1398 *params = mCaps.maxVertexShaderStorageBlocks;
1399 break;
1400 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1401 *params = mCaps.maxFragmentAtomicCounterBuffers;
1402 break;
1403 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1404 *params = mCaps.maxFragmentAtomicCounters;
1405 break;
1406 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1407 *params = mCaps.maxFragmentImageUniforms;
1408 break;
1409 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1410 *params = mCaps.maxFragmentShaderStorageBlocks;
1411 break;
1412 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1413 *params = mCaps.minProgramTextureGatherOffset;
1414 break;
1415 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1416 *params = mCaps.maxProgramTextureGatherOffset;
1417 break;
1418 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1419 *params = mCaps.maxComputeWorkGroupInvocations;
1420 break;
1421 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1422 *params = mCaps.maxComputeUniformBlocks;
1423 break;
1424 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1425 *params = mCaps.maxComputeTextureImageUnits;
1426 break;
1427 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1428 *params = mCaps.maxComputeSharedMemorySize;
1429 break;
1430 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1431 *params = mCaps.maxComputeUniformComponents;
1432 break;
1433 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1434 *params = mCaps.maxComputeAtomicCounterBuffers;
1435 break;
1436 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1437 *params = mCaps.maxComputeAtomicCounters;
1438 break;
1439 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1440 *params = mCaps.maxComputeImageUniforms;
1441 break;
1442 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1443 *params = mCaps.maxCombinedComputeUniformComponents;
1444 break;
1445 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1446 *params = mCaps.maxComputeShaderStorageBlocks;
1447 break;
1448 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1449 *params = mCaps.maxCombinedShaderOutputResources;
1450 break;
1451 case GL_MAX_UNIFORM_LOCATIONS:
1452 *params = mCaps.maxUniformLocations;
1453 break;
1454 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1455 *params = mCaps.maxAtomicCounterBufferBindings;
1456 break;
1457 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1458 *params = mCaps.maxAtomicCounterBufferSize;
1459 break;
1460 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1461 *params = mCaps.maxCombinedAtomicCounterBuffers;
1462 break;
1463 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1464 *params = mCaps.maxCombinedAtomicCounters;
1465 break;
1466 case GL_MAX_IMAGE_UNITS:
1467 *params = mCaps.maxImageUnits;
1468 break;
1469 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1470 *params = mCaps.maxCombinedImageUniforms;
1471 break;
1472 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1473 *params = mCaps.maxShaderStorageBufferBindings;
1474 break;
1475 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1476 *params = mCaps.maxCombinedShaderStorageBlocks;
1477 break;
1478 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1479 *params = mCaps.shaderStorageBufferOffsetAlignment;
1480 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001481 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001482 mGLState.getIntegerv(mState, pname, params);
1483 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001485}
1486
Jamie Madill893ab082014-05-16 16:56:10 -04001487void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001488{
Shannon Woods53a94a82014-06-24 15:20:36 -04001489 // Queries about context capabilities and maximums are answered by Context.
1490 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001491 switch (pname)
1492 {
1493 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001494 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001495 break;
1496 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001497 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001498 break;
1499 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001500 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 break;
1502 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001503 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001504 break;
1505 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001506 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001508
1509 // GL_EXT_disjoint_timer_query
1510 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001511 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001512 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001513
1514 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1515 *params = mCaps.maxShaderStorageBlockSize;
1516 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001517 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001518 UNREACHABLE();
1519 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001520 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001521}
1522
Geoff Lang70d0f492015-12-10 17:45:46 -05001523void Context::getPointerv(GLenum pname, void **params) const
1524{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001525 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001526}
1527
Martin Radev66fb8202016-07-28 11:45:20 +03001528void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001529{
Shannon Woods53a94a82014-06-24 15:20:36 -04001530 // Queries about context capabilities and maximums are answered by Context.
1531 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001532
1533 GLenum nativeType;
1534 unsigned int numParams;
1535 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001536 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001537 ASSERT(queryStatus);
1538
1539 if (nativeType == GL_INT)
1540 {
1541 switch (target)
1542 {
1543 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1544 ASSERT(index < 3u);
1545 *data = mCaps.maxComputeWorkGroupCount[index];
1546 break;
1547 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1548 ASSERT(index < 3u);
1549 *data = mCaps.maxComputeWorkGroupSize[index];
1550 break;
1551 default:
1552 mGLState.getIntegeri_v(target, index, data);
1553 }
1554 }
1555 else
1556 {
1557 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1558 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001559}
1560
Martin Radev66fb8202016-07-28 11:45:20 +03001561void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001562{
Shannon Woods53a94a82014-06-24 15:20:36 -04001563 // Queries about context capabilities and maximums are answered by Context.
1564 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001565
1566 GLenum nativeType;
1567 unsigned int numParams;
1568 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001569 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001570 ASSERT(queryStatus);
1571
1572 if (nativeType == GL_INT_64_ANGLEX)
1573 {
1574 mGLState.getInteger64i_v(target, index, data);
1575 }
1576 else
1577 {
1578 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1579 }
1580}
1581
1582void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1583{
1584 // Queries about context capabilities and maximums are answered by Context.
1585 // Queries about current GL state values are answered by State.
1586
1587 GLenum nativeType;
1588 unsigned int numParams;
1589 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001590 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001591 ASSERT(queryStatus);
1592
1593 if (nativeType == GL_BOOL)
1594 {
1595 mGLState.getBooleani_v(target, index, data);
1596 }
1597 else
1598 {
1599 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1600 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001601}
1602
Geoff Langf6db0982015-08-25 13:04:00 -04001603Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001604{
Jamie Madill1b94d432015-08-07 13:23:23 -04001605 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001606 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001607 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001608
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001609 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001610}
1611
Geoff Langf6db0982015-08-25 13:04:00 -04001612Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1613{
1614 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001615 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001616 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001617
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001619}
1620
1621Error Context::drawElements(GLenum mode,
1622 GLsizei count,
1623 GLenum type,
1624 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001625 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001626{
Jamie Madill1b94d432015-08-07 13:23:23 -04001627 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001628 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001629}
1630
1631Error Context::drawElementsInstanced(GLenum mode,
1632 GLsizei count,
1633 GLenum type,
1634 const GLvoid *indices,
1635 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001636 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001637{
1638 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001639 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1640 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001641}
1642
1643Error Context::drawRangeElements(GLenum mode,
1644 GLuint start,
1645 GLuint end,
1646 GLsizei count,
1647 GLenum type,
1648 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001649 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001650{
1651 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001652 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001653}
1654
Geoff Lang129753a2015-01-09 16:52:09 -05001655Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001657 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001658}
1659
1660Error Context::finish()
1661{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001662 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001663}
1664
Austin Kinross6ee1e782015-05-29 17:05:37 -07001665void Context::insertEventMarker(GLsizei length, const char *marker)
1666{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001667 ASSERT(mImplementation);
1668 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001669}
1670
1671void Context::pushGroupMarker(GLsizei length, const char *marker)
1672{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001673 ASSERT(mImplementation);
1674 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001675}
1676
1677void Context::popGroupMarker()
1678{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001679 ASSERT(mImplementation);
1680 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001681}
1682
Geoff Langd8605522016-04-13 10:19:12 -04001683void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1684{
1685 Program *programObject = getProgram(program);
1686 ASSERT(programObject);
1687
1688 programObject->bindUniformLocation(location, name);
1689}
1690
Sami Väisänena797e062016-05-12 15:23:40 +03001691void Context::setCoverageModulation(GLenum components)
1692{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001693 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001694}
1695
Sami Väisänene45e53b2016-05-25 10:36:04 +03001696void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1697{
1698 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1699}
1700
1701void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1702{
1703 GLfloat I[16];
1704 angle::Matrix<GLfloat>::setToIdentity(I);
1705
1706 mGLState.loadPathRenderingMatrix(matrixMode, I);
1707}
1708
1709void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1710{
1711 const auto *pathObj = mResourceManager->getPath(path);
1712 if (!pathObj)
1713 return;
1714
1715 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1716 syncRendererState();
1717
1718 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1719}
1720
1721void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1722{
1723 const auto *pathObj = mResourceManager->getPath(path);
1724 if (!pathObj)
1725 return;
1726
1727 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1728 syncRendererState();
1729
1730 mImplementation->stencilStrokePath(pathObj, reference, mask);
1731}
1732
1733void Context::coverFillPath(GLuint path, GLenum coverMode)
1734{
1735 const auto *pathObj = mResourceManager->getPath(path);
1736 if (!pathObj)
1737 return;
1738
1739 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1740 syncRendererState();
1741
1742 mImplementation->coverFillPath(pathObj, coverMode);
1743}
1744
1745void Context::coverStrokePath(GLuint path, GLenum coverMode)
1746{
1747 const auto *pathObj = mResourceManager->getPath(path);
1748 if (!pathObj)
1749 return;
1750
1751 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1752 syncRendererState();
1753
1754 mImplementation->coverStrokePath(pathObj, coverMode);
1755}
1756
1757void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1758{
1759 const auto *pathObj = mResourceManager->getPath(path);
1760 if (!pathObj)
1761 return;
1762
1763 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1764 syncRendererState();
1765
1766 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1767}
1768
1769void Context::stencilThenCoverStrokePath(GLuint path,
1770 GLint reference,
1771 GLuint mask,
1772 GLenum coverMode)
1773{
1774 const auto *pathObj = mResourceManager->getPath(path);
1775 if (!pathObj)
1776 return;
1777
1778 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1779 syncRendererState();
1780
1781 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1782}
1783
Sami Väisänend59ca052016-06-21 16:10:00 +03001784void Context::coverFillPathInstanced(GLsizei numPaths,
1785 GLenum pathNameType,
1786 const void *paths,
1787 GLuint pathBase,
1788 GLenum coverMode,
1789 GLenum transformType,
1790 const GLfloat *transformValues)
1791{
1792 const auto &pathObjects =
1793 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1794
1795 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1796 syncRendererState();
1797
1798 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1799}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001800
Sami Väisänend59ca052016-06-21 16:10:00 +03001801void Context::coverStrokePathInstanced(GLsizei numPaths,
1802 GLenum pathNameType,
1803 const void *paths,
1804 GLuint pathBase,
1805 GLenum coverMode,
1806 GLenum transformType,
1807 const GLfloat *transformValues)
1808{
1809 const auto &pathObjects =
1810 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1811
1812 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1813 syncRendererState();
1814
1815 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1816 transformValues);
1817}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001818
Sami Väisänend59ca052016-06-21 16:10:00 +03001819void Context::stencilFillPathInstanced(GLsizei numPaths,
1820 GLenum pathNameType,
1821 const void *paths,
1822 GLuint pathBase,
1823 GLenum fillMode,
1824 GLuint mask,
1825 GLenum transformType,
1826 const GLfloat *transformValues)
1827{
1828 const auto &pathObjects =
1829 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1830
1831 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1832 syncRendererState();
1833
1834 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1835 transformValues);
1836}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001837
Sami Väisänend59ca052016-06-21 16:10:00 +03001838void Context::stencilStrokePathInstanced(GLsizei numPaths,
1839 GLenum pathNameType,
1840 const void *paths,
1841 GLuint pathBase,
1842 GLint reference,
1843 GLuint mask,
1844 GLenum transformType,
1845 const GLfloat *transformValues)
1846{
1847 const auto &pathObjects =
1848 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1849
1850 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1851 syncRendererState();
1852
1853 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1854 transformValues);
1855}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001856
Sami Väisänend59ca052016-06-21 16:10:00 +03001857void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1858 GLenum pathNameType,
1859 const void *paths,
1860 GLuint pathBase,
1861 GLenum fillMode,
1862 GLuint mask,
1863 GLenum coverMode,
1864 GLenum transformType,
1865 const GLfloat *transformValues)
1866{
1867 const auto &pathObjects =
1868 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1869
1870 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1871 syncRendererState();
1872
1873 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1874 transformType, transformValues);
1875}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001876
Sami Väisänend59ca052016-06-21 16:10:00 +03001877void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1878 GLenum pathNameType,
1879 const void *paths,
1880 GLuint pathBase,
1881 GLint reference,
1882 GLuint mask,
1883 GLenum coverMode,
1884 GLenum transformType,
1885 const GLfloat *transformValues)
1886{
1887 const auto &pathObjects =
1888 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1889
1890 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1891 syncRendererState();
1892
1893 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1894 transformType, transformValues);
1895}
1896
Sami Väisänen46eaa942016-06-29 10:26:37 +03001897void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1898{
1899 auto *programObject = getProgram(program);
1900
1901 programObject->bindFragmentInputLocation(location, name);
1902}
1903
1904void Context::programPathFragmentInputGen(GLuint program,
1905 GLint location,
1906 GLenum genMode,
1907 GLint components,
1908 const GLfloat *coeffs)
1909{
1910 auto *programObject = getProgram(program);
1911
1912 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1913}
1914
Jamie Madill437fa652016-05-03 15:13:24 -04001915void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001916{
Geoff Langda5777c2014-07-11 09:52:58 -04001917 if (error.isError())
1918 {
1919 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001920
1921 if (!error.getMessage().empty())
1922 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001923 auto *debug = &mGLState.getDebug();
1924 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1925 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001926 }
Geoff Langda5777c2014-07-11 09:52:58 -04001927 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001928}
1929
1930// Get one of the recorded errors and clear its flag, if any.
1931// [OpenGL ES 2.0.24] section 2.5 page 13.
1932GLenum Context::getError()
1933{
Geoff Langda5777c2014-07-11 09:52:58 -04001934 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001935 {
Geoff Langda5777c2014-07-11 09:52:58 -04001936 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001937 }
Geoff Langda5777c2014-07-11 09:52:58 -04001938 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001939 {
Geoff Langda5777c2014-07-11 09:52:58 -04001940 GLenum error = *mErrors.begin();
1941 mErrors.erase(mErrors.begin());
1942 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001944}
1945
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001946// NOTE: this function should not assume that this context is current!
1947void Context::markContextLost()
1948{
1949 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
1950 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
1951 mContextLost = true;
1952}
1953
1954bool Context::isContextLost()
1955{
1956 return mContextLost;
1957}
1958
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001959GLenum Context::getResetStatus()
1960{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001961 // Even if the application doesn't want to know about resets, we want to know
1962 // as it will allow us to skip all the calls.
1963 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001964 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001965 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001966 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001967 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001968 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001969
1970 // EXT_robustness, section 2.6: If the reset notification behavior is
1971 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1972 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1973 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 }
1975
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1977 // status should be returned at least once, and GL_NO_ERROR should be returned
1978 // once the device has finished resetting.
1979 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001980 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001981 ASSERT(mResetStatus == GL_NO_ERROR);
1982 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001983
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001984 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001987 }
1988 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001989 else if (mResetStatus != GL_NO_ERROR)
1990 {
1991 mResetStatus = mImplementation->getResetStatus();
1992 }
Jamie Madill893ab082014-05-16 16:56:10 -04001993
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001995}
1996
1997bool Context::isResetNotificationEnabled()
1998{
1999 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2000}
2001
Corentin Walleze3b10e82015-05-20 11:06:25 -04002002const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002003{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002004 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002005}
2006
2007EGLenum Context::getClientType() const
2008{
2009 return mClientType;
2010}
2011
2012EGLenum Context::getRenderBuffer() const
2013{
Corentin Wallez37c39792015-08-20 14:19:46 -04002014 auto framebufferIt = mFramebufferMap.find(0);
2015 if (framebufferIt != mFramebufferMap.end())
2016 {
2017 const Framebuffer *framebuffer = framebufferIt->second;
2018 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2019
2020 ASSERT(backAttachment != nullptr);
2021 return backAttachment->getSurface()->getRenderBuffer();
2022 }
2023 else
2024 {
2025 return EGL_NONE;
2026 }
Régis Fénéon83107972015-02-05 12:57:44 +01002027}
2028
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002029VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002030{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002031 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002032 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2033 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002034 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002035 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002037 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002038 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002039
2040 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002041}
2042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002043TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
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 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2047 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002049 transformFeedback =
2050 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002051 transformFeedback->addRef();
2052 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002053 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002054
2055 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002056}
2057
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002058Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2059{
2060 // Can be called from Bind without a prior call to Gen.
2061 auto framebufferIt = mFramebufferMap.find(framebuffer);
2062 bool neverCreated = framebufferIt == mFramebufferMap.end();
2063 if (neverCreated || framebufferIt->second == nullptr)
2064 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002065 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002066 if (neverCreated)
2067 {
2068 mFramebufferHandleAllocator.reserve(framebuffer);
2069 mFramebufferMap[framebuffer] = newFBO;
2070 return newFBO;
2071 }
2072
2073 framebufferIt->second = newFBO;
2074 }
2075
2076 return framebufferIt->second;
2077}
2078
Geoff Langf41a7152016-09-19 15:11:17 -04002079bool Context::isTextureGenerated(GLuint texture) const
2080{
2081 return mResourceManager->isTextureGenerated(texture);
2082}
2083
2084bool Context::isBufferGenerated(GLuint buffer) const
2085{
2086 return mResourceManager->isBufferGenerated(buffer);
2087}
2088
2089bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2090{
2091 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2092}
2093
2094bool Context::isFramebufferGenerated(GLuint framebuffer) const
2095{
2096 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2097 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2098}
2099
Geoff Lang36167ab2015-12-07 10:27:14 -05002100bool Context::isVertexArrayGenerated(GLuint vertexArray)
2101{
Geoff Langf41a7152016-09-19 15:11:17 -04002102 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002103 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2104}
2105
2106bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2107{
Geoff Langf41a7152016-09-19 15:11:17 -04002108 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002109 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2110}
2111
Shannon Woods53a94a82014-06-24 15:20:36 -04002112void Context::detachTexture(GLuint texture)
2113{
2114 // Simple pass-through to State's detachTexture method, as textures do not require
2115 // allocation map management either here or in the resource manager at detach time.
2116 // Zero textures are held by the Context, and we don't attempt to request them from
2117 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002118 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002119}
2120
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121void Context::detachBuffer(GLuint buffer)
2122{
Yuly Novikov5807a532015-12-03 13:01:22 -05002123 // Simple pass-through to State's detachBuffer method, since
2124 // only buffer attachments to container objects that are bound to the current context
2125 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002126
Yuly Novikov5807a532015-12-03 13:01:22 -05002127 // [OpenGL ES 3.2] section 5.1.2 page 45:
2128 // Attachments to unbound container objects, such as
2129 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2130 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002131 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132}
2133
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134void Context::detachFramebuffer(GLuint framebuffer)
2135{
Shannon Woods53a94a82014-06-24 15:20:36 -04002136 // Framebuffer detachment is handled by Context, because 0 is a valid
2137 // Framebuffer object, and a pointer to it must be passed from Context
2138 // to State at binding time.
2139
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002140 // [OpenGL ES 2.0.24] section 4.4 page 107:
2141 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2142 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2143
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002144 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145 {
2146 bindReadFramebuffer(0);
2147 }
2148
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002149 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 {
2151 bindDrawFramebuffer(0);
2152 }
2153}
2154
2155void Context::detachRenderbuffer(GLuint renderbuffer)
2156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002158}
2159
Jamie Madill57a89722013-07-02 11:57:03 -04002160void Context::detachVertexArray(GLuint vertexArray)
2161{
Jamie Madill77a72f62015-04-14 11:18:32 -04002162 // Vertex array detachment is handled by Context, because 0 is a valid
2163 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002164 // binding time.
2165
Jamie Madill57a89722013-07-02 11:57:03 -04002166 // [OpenGL ES 3.0.2] section 2.10 page 43:
2167 // If a vertex array object that is currently bound is deleted, the binding
2168 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002169 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002170 {
2171 bindVertexArray(0);
2172 }
2173}
2174
Geoff Langc8058452014-02-03 12:04:11 -05002175void Context::detachTransformFeedback(GLuint transformFeedback)
2176{
Corentin Walleza2257da2016-04-19 16:43:12 -04002177 // Transform feedback detachment is handled by Context, because 0 is a valid
2178 // transform feedback, and a pointer to it must be passed from Context to State at
2179 // binding time.
2180
2181 // The OpenGL specification doesn't mention what should happen when the currently bound
2182 // transform feedback object is deleted. Since it is a container object, we treat it like
2183 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002184 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002185 {
2186 bindTransformFeedback(0);
2187 }
Geoff Langc8058452014-02-03 12:04:11 -05002188}
2189
Jamie Madilldc356042013-07-19 16:36:57 -04002190void Context::detachSampler(GLuint sampler)
2191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002192 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002193}
2194
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002195void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002197 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198}
2199
Jamie Madille29d1672013-07-19 16:36:57 -04002200void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2201{
Jamie Madill901b3792016-05-26 09:20:40 -04002202 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002203
2204 Sampler *samplerObject = getSampler(sampler);
2205 ASSERT(samplerObject);
2206
Geoff Lang69cce582015-09-17 13:20:36 -04002207 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002208 switch (pname)
2209 {
Geoff Lang69cce582015-09-17 13:20:36 -04002210 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2211 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2212 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2213 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2214 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2215 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2216 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2217 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2218 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2219 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2220 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002221 }
Geoff Lang69cce582015-09-17 13:20:36 -04002222 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002223}
2224
2225void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2226{
Jamie Madill901b3792016-05-26 09:20:40 -04002227 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002228
2229 Sampler *samplerObject = getSampler(sampler);
2230 ASSERT(samplerObject);
2231
Geoff Lang69cce582015-09-17 13:20:36 -04002232 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002233 switch (pname)
2234 {
Geoff Lang69cce582015-09-17 13:20:36 -04002235 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2236 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2237 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2238 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2239 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2240 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2241 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2242 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2243 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2244 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2245 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002246 }
Geoff Lang69cce582015-09-17 13:20:36 -04002247 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002248}
2249
Jamie Madill9675b802013-07-19 16:36:59 -04002250GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2251{
Jamie Madill901b3792016-05-26 09:20:40 -04002252 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002253
2254 Sampler *samplerObject = getSampler(sampler);
2255 ASSERT(samplerObject);
2256
Geoff Lang69cce582015-09-17 13:20:36 -04002257 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002258 switch (pname)
2259 {
Geoff Lang69cce582015-09-17 13:20:36 -04002260 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2261 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2262 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2263 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2264 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2265 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002266 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2267 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002268 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2269 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2270 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002271 }
Geoff Lang69cce582015-09-17 13:20:36 -04002272 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002273}
2274
2275GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2276{
Jamie Madill901b3792016-05-26 09:20:40 -04002277 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002278
2279 Sampler *samplerObject = getSampler(sampler);
2280 ASSERT(samplerObject);
2281
Geoff Lang69cce582015-09-17 13:20:36 -04002282 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002283 switch (pname)
2284 {
Geoff Lang69cce582015-09-17 13:20:36 -04002285 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2286 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2287 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2288 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2289 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2290 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2291 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2292 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2293 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2294 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2295 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002296 }
Geoff Lang69cce582015-09-17 13:20:36 -04002297 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002298}
2299
Olli Etuahof0fee072016-03-30 15:11:58 +03002300void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2301{
2302 gl::Program *programObject = getProgram(program);
2303 ASSERT(programObject != nullptr);
2304
2305 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2306 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2307}
2308
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002309void Context::initRendererString()
2310{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002311 std::ostringstream rendererString;
2312 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002313 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002314 rendererString << ")";
2315
Geoff Langcec35902014-04-16 10:52:36 -04002316 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002317}
2318
Geoff Langc287ea62016-09-16 14:46:51 -04002319const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002320{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002321 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002322}
2323
Geoff Langcec35902014-04-16 10:52:36 -04002324void Context::initExtensionStrings()
2325{
Geoff Langc287ea62016-09-16 14:46:51 -04002326 for (const auto &extensionString : mExtensions.getStrings())
2327 {
2328 mExtensionStrings.push_back(MakeStaticString(extensionString));
2329 }
Geoff Langcec35902014-04-16 10:52:36 -04002330
Geoff Langc0b9ef42014-07-02 10:02:37 -04002331 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002332 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2333 std::ostream_iterator<const char *>(combinedStringStream, " "));
2334 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002335}
2336
Geoff Langc287ea62016-09-16 14:46:51 -04002337const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002338{
2339 return mExtensionString;
2340}
2341
Geoff Langc287ea62016-09-16 14:46:51 -04002342const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002343{
2344 return mExtensionStrings[idx];
2345}
2346
2347size_t Context::getExtensionStringCount() const
2348{
2349 return mExtensionStrings.size();
2350}
2351
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002352void Context::beginTransformFeedback(GLenum primitiveMode)
2353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002354 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002355 ASSERT(transformFeedback != nullptr);
2356 ASSERT(!transformFeedback->isPaused());
2357
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002358 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002359}
2360
2361bool Context::hasActiveTransformFeedback(GLuint program) const
2362{
2363 for (auto pair : mTransformFeedbackMap)
2364 {
2365 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2366 {
2367 return true;
2368 }
2369 }
2370 return false;
2371}
2372
Geoff Langc287ea62016-09-16 14:46:51 -04002373void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002374{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002375 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002376
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002377 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002378
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002379 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002380
Martin Radev1be913c2016-07-11 17:59:16 +03002381 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002382 {
2383 // Disable ES3+ extensions
2384 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002385 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002386 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002387 }
2388
Martin Radev1be913c2016-07-11 17:59:16 +03002389 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002390 {
2391 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2392 //mExtensions.sRGB = false;
2393 }
2394
Jamie Madill00ed7a12016-05-19 13:13:38 -04002395 // Some extensions are always available because they are implemented in the GL layer.
2396 mExtensions.bindUniformLocation = true;
2397 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002398 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002399
2400 // Enable the no error extension if the context was created with the flag.
2401 mExtensions.noError = mSkipValidation;
2402
Geoff Lang70d0f492015-12-10 17:45:46 -05002403 // Explicitly enable GL_KHR_debug
2404 mExtensions.debug = true;
2405 mExtensions.maxDebugMessageLength = 1024;
2406 mExtensions.maxDebugLoggedMessages = 1024;
2407 mExtensions.maxDebugGroupStackDepth = 1024;
2408 mExtensions.maxLabelLength = 1024;
2409
Geoff Langff5b2d52016-09-07 11:32:23 -04002410 // Explicitly enable GL_ANGLE_robust_client_memory
2411 mExtensions.robustClientMemory = true;
2412
Geoff Lang301d1612014-07-09 10:34:37 -04002413 // Apply implementation limits
2414 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002415 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2416 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2417
2418 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002419
Geoff Langc287ea62016-09-16 14:46:51 -04002420 // WebGL compatibility
2421 mExtensions.webglCompatibility = webGLContext;
2422 for (const auto &extensionInfo : GetExtensionInfoMap())
2423 {
2424 // If this context is for WebGL, disable all enableable extensions
2425 if (webGLContext && extensionInfo.second.Enableable)
2426 {
2427 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2428 }
2429 }
2430
2431 // Generate texture caps
2432 updateCaps();
2433}
2434
2435void Context::updateCaps()
2436{
Geoff Lang900013c2014-07-07 11:32:19 -04002437 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002438 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002439
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002440 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002441 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2442 {
2443 GLenum format = i->first;
2444 TextureCaps formatCaps = i->second;
2445
Geoff Lang5d601382014-07-22 15:14:06 -04002446 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002447
Geoff Lang0d8b7242015-09-09 14:56:53 -04002448 // Update the format caps based on the client version and extensions.
2449 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2450 // ES3.
2451 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002452 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002453 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002454 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002455 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002456 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002457
2458 // OpenGL ES does not support multisampling with integer formats
2459 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002460 {
Geoff Langd87878e2014-09-19 15:42:59 -04002461 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002462 }
Geoff Langd87878e2014-09-19 15:42:59 -04002463
2464 if (formatCaps.texturable && formatInfo.compressed)
2465 {
2466 mCaps.compressedTextureFormats.push_back(format);
2467 }
2468
2469 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002470 }
2471}
2472
Jamie Madill1b94d432015-08-07 13:23:23 -04002473void Context::syncRendererState()
2474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002475 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2476 mImplementation->syncState(mGLState, dirtyBits);
2477 mGLState.clearDirtyBits();
2478 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002479}
2480
Jamie Madillad9f24e2016-02-12 09:27:24 -05002481void Context::syncRendererState(const State::DirtyBits &bitMask,
2482 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002483{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002484 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2485 mImplementation->syncState(mGLState, dirtyBits);
2486 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002487
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002488 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002489}
Jamie Madillc29968b2016-01-20 11:17:23 -05002490
2491void Context::blitFramebuffer(GLint srcX0,
2492 GLint srcY0,
2493 GLint srcX1,
2494 GLint srcY1,
2495 GLint dstX0,
2496 GLint dstY0,
2497 GLint dstX1,
2498 GLint dstY1,
2499 GLbitfield mask,
2500 GLenum filter)
2501{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002502 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 ASSERT(drawFramebuffer);
2504
2505 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2506 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2507
Jamie Madillad9f24e2016-02-12 09:27:24 -05002508 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002509
Jamie Madill8415b5f2016-04-26 13:41:39 -04002510 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002511}
Jamie Madillc29968b2016-01-20 11:17:23 -05002512
2513void Context::clear(GLbitfield mask)
2514{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002516 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002517}
2518
2519void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2520{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002521 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002522 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2523 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002524}
2525
2526void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2527{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002528 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002529 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2530 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002531}
2532
2533void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2534{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002535 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002536 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2537 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002538}
2539
2540void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2541{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002542 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002543 ASSERT(framebufferObject);
2544
2545 // If a buffer is not present, the clear has no effect
2546 if (framebufferObject->getDepthbuffer() == nullptr &&
2547 framebufferObject->getStencilbuffer() == nullptr)
2548 {
2549 return;
2550 }
2551
Jamie Madillad9f24e2016-02-12 09:27:24 -05002552 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002553 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2554 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002555}
2556
2557void Context::readPixels(GLint x,
2558 GLint y,
2559 GLsizei width,
2560 GLsizei height,
2561 GLenum format,
2562 GLenum type,
2563 GLvoid *pixels)
2564{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002565 if (width == 0 || height == 0)
2566 {
2567 return;
2568 }
2569
Jamie Madillad9f24e2016-02-12 09:27:24 -05002570 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002571
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002572 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 ASSERT(framebufferObject);
2574
2575 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002576 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002577}
2578
2579void Context::copyTexImage2D(GLenum target,
2580 GLint level,
2581 GLenum internalformat,
2582 GLint x,
2583 GLint y,
2584 GLsizei width,
2585 GLsizei height,
2586 GLint border)
2587{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002588 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002589 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002590
Jamie Madillc29968b2016-01-20 11:17:23 -05002591 Rectangle sourceArea(x, y, width, height);
2592
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002593 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002594 Texture *texture =
2595 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002596 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002597}
2598
2599void Context::copyTexSubImage2D(GLenum target,
2600 GLint level,
2601 GLint xoffset,
2602 GLint yoffset,
2603 GLint x,
2604 GLint y,
2605 GLsizei width,
2606 GLsizei height)
2607{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002608 if (width == 0 || height == 0)
2609 {
2610 return;
2611 }
2612
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002613 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002614 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002615
Jamie Madillc29968b2016-01-20 11:17:23 -05002616 Offset destOffset(xoffset, yoffset, 0);
2617 Rectangle sourceArea(x, y, width, height);
2618
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002619 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002620 Texture *texture =
2621 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002622 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002623}
2624
2625void Context::copyTexSubImage3D(GLenum target,
2626 GLint level,
2627 GLint xoffset,
2628 GLint yoffset,
2629 GLint zoffset,
2630 GLint x,
2631 GLint y,
2632 GLsizei width,
2633 GLsizei height)
2634{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002635 if (width == 0 || height == 0)
2636 {
2637 return;
2638 }
2639
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002640 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002641 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002642
Jamie Madillc29968b2016-01-20 11:17:23 -05002643 Offset destOffset(xoffset, yoffset, zoffset);
2644 Rectangle sourceArea(x, y, width, height);
2645
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002646 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002647 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002648 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002649}
2650
2651void Context::framebufferTexture2D(GLenum target,
2652 GLenum attachment,
2653 GLenum textarget,
2654 GLuint texture,
2655 GLint level)
2656{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002657 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002658 ASSERT(framebuffer);
2659
2660 if (texture != 0)
2661 {
2662 Texture *textureObj = getTexture(texture);
2663
2664 ImageIndex index = ImageIndex::MakeInvalid();
2665
2666 if (textarget == GL_TEXTURE_2D)
2667 {
2668 index = ImageIndex::Make2D(level);
2669 }
2670 else
2671 {
2672 ASSERT(IsCubeMapTextureTarget(textarget));
2673 index = ImageIndex::MakeCube(textarget, level);
2674 }
2675
2676 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2677 }
2678 else
2679 {
2680 framebuffer->resetAttachment(attachment);
2681 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002682
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684}
2685
2686void Context::framebufferRenderbuffer(GLenum target,
2687 GLenum attachment,
2688 GLenum renderbuffertarget,
2689 GLuint renderbuffer)
2690{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002691 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002692 ASSERT(framebuffer);
2693
2694 if (renderbuffer != 0)
2695 {
2696 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2697 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2698 renderbufferObject);
2699 }
2700 else
2701 {
2702 framebuffer->resetAttachment(attachment);
2703 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002704
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002705 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002706}
2707
2708void Context::framebufferTextureLayer(GLenum target,
2709 GLenum attachment,
2710 GLuint texture,
2711 GLint level,
2712 GLint layer)
2713{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002714 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002715 ASSERT(framebuffer);
2716
2717 if (texture != 0)
2718 {
2719 Texture *textureObject = getTexture(texture);
2720
2721 ImageIndex index = ImageIndex::MakeInvalid();
2722
2723 if (textureObject->getTarget() == GL_TEXTURE_3D)
2724 {
2725 index = ImageIndex::Make3D(level, layer);
2726 }
2727 else
2728 {
2729 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2730 index = ImageIndex::Make2DArray(level, layer);
2731 }
2732
2733 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2734 }
2735 else
2736 {
2737 framebuffer->resetAttachment(attachment);
2738 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002739
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002741}
2742
2743void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2744{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 ASSERT(framebuffer);
2747 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002748 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002749}
2750
2751void Context::readBuffer(GLenum mode)
2752{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002753 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002754 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002756}
2757
2758void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2759{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002760 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002761 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002762
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002764 ASSERT(framebuffer);
2765
2766 // The specification isn't clear what should be done when the framebuffer isn't complete.
2767 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002768 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002769}
2770
2771void Context::invalidateFramebuffer(GLenum target,
2772 GLsizei numAttachments,
2773 const GLenum *attachments)
2774{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002775 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002776 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002777
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002778 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002779 ASSERT(framebuffer);
2780
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002781 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002782 {
Jamie Madill437fa652016-05-03 15:13:24 -04002783 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002784 }
Jamie Madill437fa652016-05-03 15:13:24 -04002785
2786 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002787}
2788
2789void Context::invalidateSubFramebuffer(GLenum target,
2790 GLsizei numAttachments,
2791 const GLenum *attachments,
2792 GLint x,
2793 GLint y,
2794 GLsizei width,
2795 GLsizei height)
2796{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002797 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002799
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002800 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002801 ASSERT(framebuffer);
2802
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002804 {
Jamie Madill437fa652016-05-03 15:13:24 -04002805 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002806 }
Jamie Madill437fa652016-05-03 15:13:24 -04002807
2808 Rectangle area(x, y, width, height);
2809 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002810}
2811
Jamie Madill73a84962016-02-12 09:27:23 -05002812void Context::texImage2D(GLenum target,
2813 GLint level,
2814 GLint internalformat,
2815 GLsizei width,
2816 GLsizei height,
2817 GLint border,
2818 GLenum format,
2819 GLenum type,
2820 const GLvoid *pixels)
2821{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002822 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002823
2824 Extents size(width, height, 1);
2825 Texture *texture =
2826 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002828 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002829}
2830
2831void Context::texImage3D(GLenum target,
2832 GLint level,
2833 GLint internalformat,
2834 GLsizei width,
2835 GLsizei height,
2836 GLsizei depth,
2837 GLint border,
2838 GLenum format,
2839 GLenum type,
2840 const GLvoid *pixels)
2841{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002842 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002843
2844 Extents size(width, height, depth);
2845 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002847 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002848}
2849
2850void Context::texSubImage2D(GLenum target,
2851 GLint level,
2852 GLint xoffset,
2853 GLint yoffset,
2854 GLsizei width,
2855 GLsizei height,
2856 GLenum format,
2857 GLenum type,
2858 const GLvoid *pixels)
2859{
2860 // Zero sized uploads are valid but no-ops
2861 if (width == 0 || height == 0)
2862 {
2863 return;
2864 }
2865
Jamie Madillad9f24e2016-02-12 09:27:24 -05002866 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002867
2868 Box area(xoffset, yoffset, 0, width, height, 1);
2869 Texture *texture =
2870 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002871 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002872 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002873}
2874
2875void Context::texSubImage3D(GLenum target,
2876 GLint level,
2877 GLint xoffset,
2878 GLint yoffset,
2879 GLint zoffset,
2880 GLsizei width,
2881 GLsizei height,
2882 GLsizei depth,
2883 GLenum format,
2884 GLenum type,
2885 const GLvoid *pixels)
2886{
2887 // Zero sized uploads are valid but no-ops
2888 if (width == 0 || height == 0 || depth == 0)
2889 {
2890 return;
2891 }
2892
Jamie Madillad9f24e2016-02-12 09:27:24 -05002893 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002894
2895 Box area(xoffset, yoffset, zoffset, width, height, depth);
2896 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002898 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002899}
2900
2901void Context::compressedTexImage2D(GLenum target,
2902 GLint level,
2903 GLenum internalformat,
2904 GLsizei width,
2905 GLsizei height,
2906 GLint border,
2907 GLsizei imageSize,
2908 const GLvoid *data)
2909{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002910 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002911
2912 Extents size(width, height, 1);
2913 Texture *texture =
2914 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2916 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002917 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002918}
2919
2920void Context::compressedTexImage3D(GLenum target,
2921 GLint level,
2922 GLenum internalformat,
2923 GLsizei width,
2924 GLsizei height,
2925 GLsizei depth,
2926 GLint border,
2927 GLsizei imageSize,
2928 const GLvoid *data)
2929{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002930 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002931
2932 Extents size(width, height, depth);
2933 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2935 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002936 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002937}
2938
2939void Context::compressedTexSubImage2D(GLenum target,
2940 GLint level,
2941 GLint xoffset,
2942 GLint yoffset,
2943 GLsizei width,
2944 GLsizei height,
2945 GLenum format,
2946 GLsizei imageSize,
2947 const GLvoid *data)
2948{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002949 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002950
2951 Box area(xoffset, yoffset, 0, width, height, 1);
2952 Texture *texture =
2953 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002954 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2955 format, imageSize,
2956 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002957}
2958
2959void Context::compressedTexSubImage3D(GLenum target,
2960 GLint level,
2961 GLint xoffset,
2962 GLint yoffset,
2963 GLint zoffset,
2964 GLsizei width,
2965 GLsizei height,
2966 GLsizei depth,
2967 GLenum format,
2968 GLsizei imageSize,
2969 const GLvoid *data)
2970{
2971 // Zero sized uploads are valid but no-ops
2972 if (width == 0 || height == 0)
2973 {
2974 return;
2975 }
2976
Jamie Madillad9f24e2016-02-12 09:27:24 -05002977 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002978
2979 Box area(xoffset, yoffset, zoffset, width, height, depth);
2980 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2982 format, imageSize,
2983 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002984}
2985
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002986void Context::generateMipmap(GLenum target)
2987{
2988 Texture *texture = getTargetTexture(target);
2989 handleError(texture->generateMipmap());
2990}
2991
Geoff Langc287ea62016-09-16 14:46:51 -04002992GLboolean Context::enableExtension(const char *name)
2993{
2994 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2995 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2996 const auto &extension = extensionInfos.at(name);
2997 ASSERT(extension.Enableable);
2998
2999 if (mExtensions.*(extension.ExtensionsMember))
3000 {
3001 // Extension already enabled
3002 return GL_TRUE;
3003 }
3004
3005 const auto &nativeExtensions = mImplementation->getNativeExtensions();
3006 if (!(nativeExtensions.*(extension.ExtensionsMember)))
3007 {
3008 // Underlying implementation does not support this valid extension
3009 return GL_FALSE;
3010 }
3011
3012 mExtensions.*(extension.ExtensionsMember) = true;
3013 updateCaps();
3014 initExtensionStrings();
3015 return GL_TRUE;
3016}
3017
Geoff Lang97073d12016-04-20 10:42:34 -07003018void Context::copyTextureCHROMIUM(GLuint sourceId,
3019 GLuint destId,
3020 GLint internalFormat,
3021 GLenum destType,
3022 GLboolean unpackFlipY,
3023 GLboolean unpackPremultiplyAlpha,
3024 GLboolean unpackUnmultiplyAlpha)
3025{
3026 syncStateForTexImage();
3027
3028 gl::Texture *sourceTexture = getTexture(sourceId);
3029 gl::Texture *destTexture = getTexture(destId);
3030 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3031 unpackPremultiplyAlpha == GL_TRUE,
3032 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3033}
3034
3035void Context::copySubTextureCHROMIUM(GLuint sourceId,
3036 GLuint destId,
3037 GLint xoffset,
3038 GLint yoffset,
3039 GLint x,
3040 GLint y,
3041 GLsizei width,
3042 GLsizei height,
3043 GLboolean unpackFlipY,
3044 GLboolean unpackPremultiplyAlpha,
3045 GLboolean unpackUnmultiplyAlpha)
3046{
3047 // Zero sized copies are valid but no-ops
3048 if (width == 0 || height == 0)
3049 {
3050 return;
3051 }
3052
3053 syncStateForTexImage();
3054
3055 gl::Texture *sourceTexture = getTexture(sourceId);
3056 gl::Texture *destTexture = getTexture(destId);
3057 Offset offset(xoffset, yoffset, 0);
3058 Rectangle area(x, y, width, height);
3059 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3060 unpackPremultiplyAlpha == GL_TRUE,
3061 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3062}
3063
Geoff Lang47110bf2016-04-20 11:13:22 -07003064void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3065{
3066 syncStateForTexImage();
3067
3068 gl::Texture *sourceTexture = getTexture(sourceId);
3069 gl::Texture *destTexture = getTexture(destId);
3070 handleError(destTexture->copyCompressedTexture(sourceTexture));
3071}
3072
Olli Etuaho4f667482016-03-30 15:56:35 +03003073void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3074{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003075 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003076 ASSERT(buffer);
3077
3078 if (!buffer->isMapped())
3079 {
3080 *params = nullptr;
3081 }
3082 else
3083 {
3084 *params = buffer->getMapPointer();
3085 }
3086}
3087
3088GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3089{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003090 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003091 ASSERT(buffer);
3092
3093 Error error = buffer->map(access);
3094 if (error.isError())
3095 {
Jamie Madill437fa652016-05-03 15:13:24 -04003096 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003097 return nullptr;
3098 }
3099
3100 return buffer->getMapPointer();
3101}
3102
3103GLboolean Context::unmapBuffer(GLenum target)
3104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003105 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003106 ASSERT(buffer);
3107
3108 GLboolean result;
3109 Error error = buffer->unmap(&result);
3110 if (error.isError())
3111 {
Jamie Madill437fa652016-05-03 15:13:24 -04003112 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003113 return GL_FALSE;
3114 }
3115
3116 return result;
3117}
3118
3119GLvoid *Context::mapBufferRange(GLenum target,
3120 GLintptr offset,
3121 GLsizeiptr length,
3122 GLbitfield access)
3123{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003125 ASSERT(buffer);
3126
3127 Error error = buffer->mapRange(offset, length, access);
3128 if (error.isError())
3129 {
Jamie Madill437fa652016-05-03 15:13:24 -04003130 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003131 return nullptr;
3132 }
3133
3134 return buffer->getMapPointer();
3135}
3136
3137void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3138{
3139 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3140}
3141
Jamie Madillad9f24e2016-02-12 09:27:24 -05003142void Context::syncStateForReadPixels()
3143{
3144 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3145}
3146
3147void Context::syncStateForTexImage()
3148{
3149 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3150}
3151
3152void Context::syncStateForClear()
3153{
3154 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3155}
3156
3157void Context::syncStateForBlit()
3158{
3159 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3160}
3161
Jamie Madillc20ab272016-06-09 07:20:46 -07003162void Context::activeTexture(GLenum texture)
3163{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003164 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003165}
3166
3167void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3168{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003169 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003170}
3171
3172void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3173{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003174 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003175}
3176
3177void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3178{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003180}
3181
3182void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3183{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003184 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003185}
3186
3187void Context::clearDepthf(GLclampf depth)
3188{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003190}
3191
3192void Context::clearStencil(GLint s)
3193{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003195}
3196
3197void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003199 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003200}
3201
3202void Context::cullFace(GLenum mode)
3203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003204 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003205}
3206
3207void Context::depthFunc(GLenum func)
3208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210}
3211
3212void Context::depthMask(GLboolean flag)
3213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003214 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003215}
3216
3217void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003220}
3221
3222void Context::disable(GLenum cap)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::disableVertexAttribArray(GLuint index)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::enable(GLenum cap)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::enableVertexAttribArray(GLuint index)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::frontFace(GLenum mode)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::hint(GLenum target, GLenum mode)
3248{
3249 switch (target)
3250 {
3251 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003252 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003253 break;
3254
3255 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257 break;
3258
3259 default:
3260 UNREACHABLE();
3261 return;
3262 }
3263}
3264
3265void Context::lineWidth(GLfloat width)
3266{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003267 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003268}
3269
3270void Context::pixelStorei(GLenum pname, GLint param)
3271{
3272 switch (pname)
3273 {
3274 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003275 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003276 break;
3277
3278 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280 break;
3281
3282 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003283 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003284 break;
3285
3286 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003287 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003288 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003289 break;
3290
3291 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003292 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003294 break;
3295
3296 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003297 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003302 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003303 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003304 break;
3305
3306 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003307 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309 break;
3310
3311 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003312 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314 break;
3315
3316 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003317 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 break;
3320
3321 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003322 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003323 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003324 break;
3325
3326 default:
3327 UNREACHABLE();
3328 return;
3329 }
3330}
3331
3332void Context::polygonOffset(GLfloat factor, GLfloat units)
3333{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335}
3336
3337void Context::sampleCoverage(GLclampf value, GLboolean invert)
3338{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340}
3341
3342void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3348{
3349 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3350 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352 }
3353
3354 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3355 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003356 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003357 }
3358}
3359
3360void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3361{
3362 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3363 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003364 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003365 }
3366
3367 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3368 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370 }
3371}
3372
3373void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3374{
3375 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3376 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003377 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003378 }
3379
3380 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3381 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003382 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003383 }
3384}
3385
3386void Context::vertexAttrib1f(GLuint index, GLfloat x)
3387{
3388 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003390}
3391
3392void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3393{
3394 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003395 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003396}
3397
3398void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3399{
3400 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003402}
3403
3404void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3405{
3406 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003407 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003408}
3409
3410void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3411{
3412 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3417{
3418 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003419 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3423{
3424 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3429{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
3433void Context::vertexAttribPointer(GLuint index,
3434 GLint size,
3435 GLenum type,
3436 GLboolean normalized,
3437 GLsizei stride,
3438 const GLvoid *ptr)
3439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3441 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003442}
3443
3444void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3445{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003446 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
3449void Context::vertexAttribIPointer(GLuint index,
3450 GLint size,
3451 GLenum type,
3452 GLsizei stride,
3453 const GLvoid *pointer)
3454{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003455 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3456 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3460{
3461 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003462 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3466{
3467 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003468 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003469}
3470
3471void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3472{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003473 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003474}
3475
3476void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3477{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479}
3480
3481void Context::debugMessageControl(GLenum source,
3482 GLenum type,
3483 GLenum severity,
3484 GLsizei count,
3485 const GLuint *ids,
3486 GLboolean enabled)
3487{
3488 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3490 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003491}
3492
3493void Context::debugMessageInsert(GLenum source,
3494 GLenum type,
3495 GLuint id,
3496 GLenum severity,
3497 GLsizei length,
3498 const GLchar *buf)
3499{
3500 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003502}
3503
3504void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3505{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003506 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003507}
3508
3509GLuint Context::getDebugMessageLog(GLuint count,
3510 GLsizei bufSize,
3511 GLenum *sources,
3512 GLenum *types,
3513 GLuint *ids,
3514 GLenum *severities,
3515 GLsizei *lengths,
3516 GLchar *messageLog)
3517{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003518 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3519 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003520}
3521
3522void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3523{
3524 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003525 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::popDebugGroup()
3529{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003530 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003531}
3532
Jamie Madill29639852016-09-02 15:00:09 -04003533void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3534{
3535 Buffer *buffer = mGLState.getTargetBuffer(target);
3536 ASSERT(buffer);
3537 handleError(buffer->bufferData(target, data, size, usage));
3538}
3539
3540void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3541{
3542 if (data == nullptr)
3543 {
3544 return;
3545 }
3546
3547 Buffer *buffer = mGLState.getTargetBuffer(target);
3548 ASSERT(buffer);
3549 handleError(buffer->bufferSubData(target, data, size, offset));
3550}
3551
Jamie Madillef300b12016-10-07 15:12:09 -04003552void Context::attachShader(GLuint program, GLuint shader)
3553{
3554 auto programObject = mResourceManager->getProgram(program);
3555 auto shaderObject = mResourceManager->getShader(shader);
3556 ASSERT(programObject && shaderObject);
3557 programObject->attachShader(shaderObject);
3558}
3559
Jamie Madillc29968b2016-01-20 11:17:23 -05003560} // namespace gl