blob: c4124b31cfee8ea48fca04638d75a5e4bde19e77 [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
Geoff Lang48dcae72014-02-05 16:28:24 -0500820Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821{
822 return mResourceManager->getShader(handle);
823}
824
Geoff Lang48dcae72014-02-05 16:28:24 -0500825Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826{
827 return mResourceManager->getProgram(handle);
828}
829
Jamie Madill570f7c82014-07-03 10:38:54 -0400830Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831{
832 return mResourceManager->getTexture(handle);
833}
834
Geoff Lang70d0f492015-12-10 17:45:46 -0500835Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000836{
837 return mResourceManager->getRenderbuffer(handle);
838}
839
Jamie Madillcd055f82013-07-26 11:55:15 -0400840FenceSync *Context::getFenceSync(GLsync handle) const
841{
Minmin Gong794e0002015-04-07 18:31:54 -0700842 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400843}
844
Jamie Madill57a89722013-07-02 11:57:03 -0400845VertexArray *Context::getVertexArray(GLuint handle) const
846{
847 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500848 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400849}
850
Jamie Madilldc356042013-07-19 16:36:57 -0400851Sampler *Context::getSampler(GLuint handle) const
852{
853 return mResourceManager->getSampler(handle);
854}
855
Geoff Langc8058452014-02-03 12:04:11 -0500856TransformFeedback *Context::getTransformFeedback(GLuint handle) const
857{
Geoff Lang36167ab2015-12-07 10:27:14 -0500858 auto iter = mTransformFeedbackMap.find(handle);
859 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500860}
861
Geoff Lang70d0f492015-12-10 17:45:46 -0500862LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
863{
864 switch (identifier)
865 {
866 case GL_BUFFER:
867 return getBuffer(name);
868 case GL_SHADER:
869 return getShader(name);
870 case GL_PROGRAM:
871 return getProgram(name);
872 case GL_VERTEX_ARRAY:
873 return getVertexArray(name);
874 case GL_QUERY:
875 return getQuery(name);
876 case GL_TRANSFORM_FEEDBACK:
877 return getTransformFeedback(name);
878 case GL_SAMPLER:
879 return getSampler(name);
880 case GL_TEXTURE:
881 return getTexture(name);
882 case GL_RENDERBUFFER:
883 return getRenderbuffer(name);
884 case GL_FRAMEBUFFER:
885 return getFramebuffer(name);
886 default:
887 UNREACHABLE();
888 return nullptr;
889 }
890}
891
892LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
893{
894 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
895}
896
Martin Radev9d901792016-07-15 15:58:58 +0300897void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
898{
899 LabeledObject *object = getLabeledObject(identifier, name);
900 ASSERT(object != nullptr);
901
902 std::string labelName = GetObjectLabelFromPointer(length, label);
903 object->setLabel(labelName);
904}
905
906void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
907{
908 LabeledObject *object = getLabeledObjectFromPtr(ptr);
909 ASSERT(object != nullptr);
910
911 std::string labelName = GetObjectLabelFromPointer(length, label);
912 object->setLabel(labelName);
913}
914
915void Context::getObjectLabel(GLenum identifier,
916 GLuint name,
917 GLsizei bufSize,
918 GLsizei *length,
919 GLchar *label) const
920{
921 LabeledObject *object = getLabeledObject(identifier, name);
922 ASSERT(object != nullptr);
923
924 const std::string &objectLabel = object->getLabel();
925 GetObjectLabelBase(objectLabel, bufSize, length, label);
926}
927
928void Context::getObjectPtrLabel(const void *ptr,
929 GLsizei bufSize,
930 GLsizei *length,
931 GLchar *label) const
932{
933 LabeledObject *object = getLabeledObjectFromPtr(ptr);
934 ASSERT(object != nullptr);
935
936 const std::string &objectLabel = object->getLabel();
937 GetObjectLabelBase(objectLabel, bufSize, length, label);
938}
939
Jamie Madilldc356042013-07-19 16:36:57 -0400940bool Context::isSampler(GLuint samplerName) const
941{
942 return mResourceManager->isSampler(samplerName);
943}
944
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500945void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000946{
Jamie Madill901b3792016-05-26 09:20:40 -0400947 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700948 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949}
950
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500951void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000952{
Jamie Madill901b3792016-05-26 09:20:40 -0400953 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700954 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955}
956
Jamie Madilldedd7b92014-11-05 16:30:36 -0500957void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500959 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960
Jamie Madilldedd7b92014-11-05 16:30:36 -0500961 if (handle == 0)
962 {
963 texture = mZeroTextures[target].get();
964 }
965 else
966 {
Jamie Madill901b3792016-05-26 09:20:40 -0400967 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500968 }
969
970 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700971 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000972}
973
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500974void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700977 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500980void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500982 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987{
Jamie Madill901b3792016-05-26 09:20:40 -0400988 Renderbuffer *renderbuffer =
989 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000991}
992
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500993void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400994{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700996 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400997}
998
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500999void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001000{
Geoff Lang76b10c92014-09-05 16:28:14 -04001001 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001002 Sampler *sampler =
1003 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001004 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001005}
1006
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001007void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001008{
Jamie Madill901b3792016-05-26 09:20:40 -04001009 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001010 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001011}
1012
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001013void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1014 GLuint index,
1015 GLintptr offset,
1016 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001017{
Jamie Madill901b3792016-05-26 09:20:40 -04001018 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001023{
Jamie Madill901b3792016-05-26 09:20:40 -04001024 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001025 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001026}
1027
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001028void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1029 GLuint index,
1030 GLintptr offset,
1031 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001032{
Jamie Madill901b3792016-05-26 09:20:40 -04001033 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001034 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001035}
1036
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001037void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001038{
Jamie Madill901b3792016-05-26 09:20:40 -04001039 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001040 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001041}
1042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001043void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001044{
Jamie Madill901b3792016-05-26 09:20:40 -04001045 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001046 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001047}
1048
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001049void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001050{
Jamie Madill901b3792016-05-26 09:20:40 -04001051 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001056{
Jamie Madill901b3792016-05-26 09:20:40 -04001057 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001058 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001059}
1060
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001061void Context::useProgram(GLuint program)
1062{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001067{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001068 TransformFeedback *transformFeedback =
1069 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001070 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001071}
1072
Geoff Lang5aad9672014-09-08 11:10:42 -04001073Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001074{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001075 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001076 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077
Geoff Lang5aad9672014-09-08 11:10:42 -04001078 // begin query
1079 Error error = queryObject->begin();
1080 if (error.isError())
1081 {
1082 return error;
1083 }
1084
1085 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087
Geoff Lang5aad9672014-09-08 11:10:42 -04001088 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089}
1090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001092{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001094 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097
Geoff Lang5aad9672014-09-08 11:10:42 -04001098 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001099 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001100
1101 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001102}
1103
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001104Error Context::queryCounter(GLuint id, GLenum target)
1105{
1106 ASSERT(target == GL_TIMESTAMP_EXT);
1107
1108 Query *queryObject = getQuery(id, true, target);
1109 ASSERT(queryObject);
1110
1111 return queryObject->queryCounter();
1112}
1113
1114void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1115{
1116 switch (pname)
1117 {
1118 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001119 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001120 break;
1121 case GL_QUERY_COUNTER_BITS_EXT:
1122 switch (target)
1123 {
1124 case GL_TIME_ELAPSED_EXT:
1125 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1126 break;
1127 case GL_TIMESTAMP_EXT:
1128 params[0] = getExtensions().queryCounterBitsTimestamp;
1129 break;
1130 default:
1131 UNREACHABLE();
1132 params[0] = 0;
1133 break;
1134 }
1135 break;
1136 default:
1137 UNREACHABLE();
1138 return;
1139 }
1140}
1141
1142Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1143{
1144 return GetQueryObjectParameter(this, id, pname, params);
1145}
1146
1147Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1148{
1149 return GetQueryObjectParameter(this, id, pname, params);
1150}
1151
1152Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1153{
1154 return GetQueryObjectParameter(this, id, pname, params);
1155}
1156
1157Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1158{
1159 return GetQueryObjectParameter(this, id, pname, params);
1160}
1161
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001162Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001163{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001164 auto framebufferIt = mFramebufferMap.find(handle);
1165 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166}
1167
Jamie Madill33dc8432013-07-26 11:55:05 -04001168FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001170 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171
Jamie Madill33dc8432013-07-26 11:55:05 -04001172 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173 {
1174 return NULL;
1175 }
1176 else
1177 {
1178 return fence->second;
1179 }
1180}
1181
1182Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1183{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001184 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185
1186 if (query == mQueryMap.end())
1187 {
1188 return NULL;
1189 }
1190 else
1191 {
1192 if (!query->second && create)
1193 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001194 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 query->second->addRef();
1196 }
1197 return query->second;
1198 }
1199}
1200
Geoff Lang70d0f492015-12-10 17:45:46 -05001201Query *Context::getQuery(GLuint handle) const
1202{
1203 auto iter = mQueryMap.find(handle);
1204 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1205}
1206
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001207Texture *Context::getTargetTexture(GLenum target) const
1208{
Ian Ewellbda75592016-04-18 17:25:54 -04001209 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001210 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001211}
1212
Geoff Lang76b10c92014-09-05 16:28:14 -04001213Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001214{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001215 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216}
1217
Geoff Lang492a7e42014-11-05 13:27:06 -05001218Compiler *Context::getCompiler() const
1219{
1220 return mCompiler;
1221}
1222
Jamie Madill893ab082014-05-16 16:56:10 -04001223void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001224{
1225 switch (pname)
1226 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001227 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001228 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001230 mGLState.getBooleanv(pname, params);
1231 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233}
1234
Jamie Madill893ab082014-05-16 16:56:10 -04001235void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236{
Shannon Woods53a94a82014-06-24 15:20:36 -04001237 // Queries about context capabilities and maximums are answered by Context.
1238 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001239 switch (pname)
1240 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001242 params[0] = mCaps.minAliasedLineWidth;
1243 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 break;
1245 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001246 params[0] = mCaps.minAliasedPointSize;
1247 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001249 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001250 ASSERT(mExtensions.textureFilterAnisotropic);
1251 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001252 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001253 case GL_MAX_TEXTURE_LOD_BIAS:
1254 *params = mCaps.maxLODBias;
1255 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001256
1257 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1258 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1259 {
1260 ASSERT(mExtensions.pathRendering);
1261 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1262 memcpy(params, m, 16 * sizeof(GLfloat));
1263 }
1264 break;
1265
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001267 mGLState.getFloatv(pname, params);
1268 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270}
1271
Jamie Madill893ab082014-05-16 16:56:10 -04001272void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273{
Shannon Woods53a94a82014-06-24 15:20:36 -04001274 // Queries about context capabilities and maximums are answered by Context.
1275 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001276
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001277 switch (pname)
1278 {
Geoff Lang301d1612014-07-09 10:34:37 -04001279 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1280 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1281 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001282 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1283 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1284 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001285 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1286 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1287 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001288 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001289 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1290 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1291 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001292 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001293 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001294 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1295 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1296 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1297 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001298 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1299 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001300 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1301 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001302 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001303 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1304 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1305 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1306 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001307 case GL_MAJOR_VERSION:
1308 *params = mClientMajorVersion;
1309 break;
1310 case GL_MINOR_VERSION:
1311 *params = mClientMinorVersion;
1312 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001313 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1314 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001315 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1316 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1317 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001318 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1319 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1320 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001321 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 case GL_MAX_VIEWPORT_DIMS:
1323 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001324 params[0] = mCaps.maxViewportWidth;
1325 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 }
1327 break;
1328 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001329 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1332 *params = mResetStrategy;
1333 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001334 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001335 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001336 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001337 case GL_SHADER_BINARY_FORMATS:
1338 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1339 break;
1340 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001341 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001342 break;
1343 case GL_PROGRAM_BINARY_FORMATS:
1344 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001345 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001346 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001347 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001348 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001349
1350 // GL_KHR_debug
1351 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1352 *params = mExtensions.maxDebugMessageLength;
1353 break;
1354 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1355 *params = mExtensions.maxDebugLoggedMessages;
1356 break;
1357 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1358 *params = mExtensions.maxDebugGroupStackDepth;
1359 break;
1360 case GL_MAX_LABEL_LENGTH:
1361 *params = mExtensions.maxLabelLength;
1362 break;
1363
Ian Ewell53f59f42016-01-28 17:36:55 -05001364 // GL_EXT_disjoint_timer_query
1365 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001366 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001367 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001368 case GL_MAX_FRAMEBUFFER_WIDTH:
1369 *params = mCaps.maxFramebufferWidth;
1370 break;
1371 case GL_MAX_FRAMEBUFFER_HEIGHT:
1372 *params = mCaps.maxFramebufferHeight;
1373 break;
1374 case GL_MAX_FRAMEBUFFER_SAMPLES:
1375 *params = mCaps.maxFramebufferSamples;
1376 break;
1377 case GL_MAX_SAMPLE_MASK_WORDS:
1378 *params = mCaps.maxSampleMaskWords;
1379 break;
1380 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1381 *params = mCaps.maxColorTextureSamples;
1382 break;
1383 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1384 *params = mCaps.maxDepthTextureSamples;
1385 break;
1386 case GL_MAX_INTEGER_SAMPLES:
1387 *params = mCaps.maxIntegerSamples;
1388 break;
1389 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1390 *params = mCaps.maxVertexAttribRelativeOffset;
1391 break;
1392 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1393 *params = mCaps.maxVertexAttribBindings;
1394 break;
1395 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1396 *params = mCaps.maxVertexAttribStride;
1397 break;
1398 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1399 *params = mCaps.maxVertexAtomicCounterBuffers;
1400 break;
1401 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1402 *params = mCaps.maxVertexAtomicCounters;
1403 break;
1404 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1405 *params = mCaps.maxVertexImageUniforms;
1406 break;
1407 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1408 *params = mCaps.maxVertexShaderStorageBlocks;
1409 break;
1410 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1411 *params = mCaps.maxFragmentAtomicCounterBuffers;
1412 break;
1413 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1414 *params = mCaps.maxFragmentAtomicCounters;
1415 break;
1416 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1417 *params = mCaps.maxFragmentImageUniforms;
1418 break;
1419 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1420 *params = mCaps.maxFragmentShaderStorageBlocks;
1421 break;
1422 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1423 *params = mCaps.minProgramTextureGatherOffset;
1424 break;
1425 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1426 *params = mCaps.maxProgramTextureGatherOffset;
1427 break;
1428 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1429 *params = mCaps.maxComputeWorkGroupInvocations;
1430 break;
1431 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1432 *params = mCaps.maxComputeUniformBlocks;
1433 break;
1434 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1435 *params = mCaps.maxComputeTextureImageUnits;
1436 break;
1437 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1438 *params = mCaps.maxComputeSharedMemorySize;
1439 break;
1440 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1441 *params = mCaps.maxComputeUniformComponents;
1442 break;
1443 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1444 *params = mCaps.maxComputeAtomicCounterBuffers;
1445 break;
1446 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1447 *params = mCaps.maxComputeAtomicCounters;
1448 break;
1449 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1450 *params = mCaps.maxComputeImageUniforms;
1451 break;
1452 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1453 *params = mCaps.maxCombinedComputeUniformComponents;
1454 break;
1455 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1456 *params = mCaps.maxComputeShaderStorageBlocks;
1457 break;
1458 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1459 *params = mCaps.maxCombinedShaderOutputResources;
1460 break;
1461 case GL_MAX_UNIFORM_LOCATIONS:
1462 *params = mCaps.maxUniformLocations;
1463 break;
1464 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1465 *params = mCaps.maxAtomicCounterBufferBindings;
1466 break;
1467 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1468 *params = mCaps.maxAtomicCounterBufferSize;
1469 break;
1470 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1471 *params = mCaps.maxCombinedAtomicCounterBuffers;
1472 break;
1473 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1474 *params = mCaps.maxCombinedAtomicCounters;
1475 break;
1476 case GL_MAX_IMAGE_UNITS:
1477 *params = mCaps.maxImageUnits;
1478 break;
1479 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1480 *params = mCaps.maxCombinedImageUniforms;
1481 break;
1482 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1483 *params = mCaps.maxShaderStorageBufferBindings;
1484 break;
1485 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1486 *params = mCaps.maxCombinedShaderStorageBlocks;
1487 break;
1488 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1489 *params = mCaps.shaderStorageBufferOffsetAlignment;
1490 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001492 mGLState.getIntegerv(mState, pname, params);
1493 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001494 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001495}
1496
Jamie Madill893ab082014-05-16 16:56:10 -04001497void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001498{
Shannon Woods53a94a82014-06-24 15:20:36 -04001499 // Queries about context capabilities and maximums are answered by Context.
1500 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 switch (pname)
1502 {
1503 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001504 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001505 break;
1506 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001507 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508 break;
1509 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001510 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001511 break;
1512 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001513 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001514 break;
1515 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001516 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001517 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001518
1519 // GL_EXT_disjoint_timer_query
1520 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001521 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001522 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001523
1524 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1525 *params = mCaps.maxShaderStorageBlockSize;
1526 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001527 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001528 UNREACHABLE();
1529 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001530 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001531}
1532
Geoff Lang70d0f492015-12-10 17:45:46 -05001533void Context::getPointerv(GLenum pname, void **params) const
1534{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001535 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001536}
1537
Martin Radev66fb8202016-07-28 11:45:20 +03001538void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001539{
Shannon Woods53a94a82014-06-24 15:20:36 -04001540 // Queries about context capabilities and maximums are answered by Context.
1541 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001542
1543 GLenum nativeType;
1544 unsigned int numParams;
1545 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001546 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001547 ASSERT(queryStatus);
1548
1549 if (nativeType == GL_INT)
1550 {
1551 switch (target)
1552 {
1553 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1554 ASSERT(index < 3u);
1555 *data = mCaps.maxComputeWorkGroupCount[index];
1556 break;
1557 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1558 ASSERT(index < 3u);
1559 *data = mCaps.maxComputeWorkGroupSize[index];
1560 break;
1561 default:
1562 mGLState.getIntegeri_v(target, index, data);
1563 }
1564 }
1565 else
1566 {
1567 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1568 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001569}
1570
Martin Radev66fb8202016-07-28 11:45:20 +03001571void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001572{
Shannon Woods53a94a82014-06-24 15:20:36 -04001573 // Queries about context capabilities and maximums are answered by Context.
1574 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001575
1576 GLenum nativeType;
1577 unsigned int numParams;
1578 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001579 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001580 ASSERT(queryStatus);
1581
1582 if (nativeType == GL_INT_64_ANGLEX)
1583 {
1584 mGLState.getInteger64i_v(target, index, data);
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
1590}
1591
1592void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1593{
1594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
1596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001600 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001601 ASSERT(queryStatus);
1602
1603 if (nativeType == GL_BOOL)
1604 {
1605 mGLState.getBooleani_v(target, index, data);
1606 }
1607 else
1608 {
1609 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1610 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001611}
1612
Geoff Langf6db0982015-08-25 13:04:00 -04001613Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614{
Jamie Madill1b94d432015-08-07 13:23:23 -04001615 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001616 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001617 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001618
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001619 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001620}
1621
Geoff Langf6db0982015-08-25 13:04:00 -04001622Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1623{
1624 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001625 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001626 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001627
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001628 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001629}
1630
1631Error Context::drawElements(GLenum mode,
1632 GLsizei count,
1633 GLenum type,
1634 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001635 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636{
Jamie Madill1b94d432015-08-07 13:23:23 -04001637 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001638 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001639}
1640
1641Error Context::drawElementsInstanced(GLenum mode,
1642 GLsizei count,
1643 GLenum type,
1644 const GLvoid *indices,
1645 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001646 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001647{
1648 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001649 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1650 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001651}
1652
1653Error Context::drawRangeElements(GLenum mode,
1654 GLuint start,
1655 GLuint end,
1656 GLsizei count,
1657 GLenum type,
1658 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001659 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001660{
1661 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001662 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001663}
1664
Geoff Lang129753a2015-01-09 16:52:09 -05001665Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001667 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001668}
1669
1670Error Context::finish()
1671{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001672 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673}
1674
Austin Kinross6ee1e782015-05-29 17:05:37 -07001675void Context::insertEventMarker(GLsizei length, const char *marker)
1676{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001677 ASSERT(mImplementation);
1678 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001679}
1680
1681void Context::pushGroupMarker(GLsizei length, const char *marker)
1682{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001683 ASSERT(mImplementation);
1684 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001685}
1686
1687void Context::popGroupMarker()
1688{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001689 ASSERT(mImplementation);
1690 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001691}
1692
Geoff Langd8605522016-04-13 10:19:12 -04001693void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1694{
1695 Program *programObject = getProgram(program);
1696 ASSERT(programObject);
1697
1698 programObject->bindUniformLocation(location, name);
1699}
1700
Sami Väisänena797e062016-05-12 15:23:40 +03001701void Context::setCoverageModulation(GLenum components)
1702{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001703 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001704}
1705
Sami Väisänene45e53b2016-05-25 10:36:04 +03001706void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1707{
1708 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1709}
1710
1711void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1712{
1713 GLfloat I[16];
1714 angle::Matrix<GLfloat>::setToIdentity(I);
1715
1716 mGLState.loadPathRenderingMatrix(matrixMode, I);
1717}
1718
1719void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1720{
1721 const auto *pathObj = mResourceManager->getPath(path);
1722 if (!pathObj)
1723 return;
1724
1725 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1726 syncRendererState();
1727
1728 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1729}
1730
1731void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1732{
1733 const auto *pathObj = mResourceManager->getPath(path);
1734 if (!pathObj)
1735 return;
1736
1737 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1738 syncRendererState();
1739
1740 mImplementation->stencilStrokePath(pathObj, reference, mask);
1741}
1742
1743void Context::coverFillPath(GLuint path, GLenum coverMode)
1744{
1745 const auto *pathObj = mResourceManager->getPath(path);
1746 if (!pathObj)
1747 return;
1748
1749 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1750 syncRendererState();
1751
1752 mImplementation->coverFillPath(pathObj, coverMode);
1753}
1754
1755void Context::coverStrokePath(GLuint path, GLenum coverMode)
1756{
1757 const auto *pathObj = mResourceManager->getPath(path);
1758 if (!pathObj)
1759 return;
1760
1761 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1762 syncRendererState();
1763
1764 mImplementation->coverStrokePath(pathObj, coverMode);
1765}
1766
1767void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1768{
1769 const auto *pathObj = mResourceManager->getPath(path);
1770 if (!pathObj)
1771 return;
1772
1773 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1774 syncRendererState();
1775
1776 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1777}
1778
1779void Context::stencilThenCoverStrokePath(GLuint path,
1780 GLint reference,
1781 GLuint mask,
1782 GLenum coverMode)
1783{
1784 const auto *pathObj = mResourceManager->getPath(path);
1785 if (!pathObj)
1786 return;
1787
1788 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1789 syncRendererState();
1790
1791 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1792}
1793
Sami Väisänend59ca052016-06-21 16:10:00 +03001794void Context::coverFillPathInstanced(GLsizei numPaths,
1795 GLenum pathNameType,
1796 const void *paths,
1797 GLuint pathBase,
1798 GLenum coverMode,
1799 GLenum transformType,
1800 const GLfloat *transformValues)
1801{
1802 const auto &pathObjects =
1803 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1804
1805 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1806 syncRendererState();
1807
1808 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1809}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001810
Sami Väisänend59ca052016-06-21 16:10:00 +03001811void Context::coverStrokePathInstanced(GLsizei numPaths,
1812 GLenum pathNameType,
1813 const void *paths,
1814 GLuint pathBase,
1815 GLenum coverMode,
1816 GLenum transformType,
1817 const GLfloat *transformValues)
1818{
1819 const auto &pathObjects =
1820 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1821
1822 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1823 syncRendererState();
1824
1825 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1826 transformValues);
1827}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001828
Sami Väisänend59ca052016-06-21 16:10:00 +03001829void Context::stencilFillPathInstanced(GLsizei numPaths,
1830 GLenum pathNameType,
1831 const void *paths,
1832 GLuint pathBase,
1833 GLenum fillMode,
1834 GLuint mask,
1835 GLenum transformType,
1836 const GLfloat *transformValues)
1837{
1838 const auto &pathObjects =
1839 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1840
1841 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1842 syncRendererState();
1843
1844 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1845 transformValues);
1846}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001847
Sami Väisänend59ca052016-06-21 16:10:00 +03001848void Context::stencilStrokePathInstanced(GLsizei numPaths,
1849 GLenum pathNameType,
1850 const void *paths,
1851 GLuint pathBase,
1852 GLint reference,
1853 GLuint mask,
1854 GLenum transformType,
1855 const GLfloat *transformValues)
1856{
1857 const auto &pathObjects =
1858 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1859
1860 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1861 syncRendererState();
1862
1863 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1864 transformValues);
1865}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001866
Sami Väisänend59ca052016-06-21 16:10:00 +03001867void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1868 GLenum pathNameType,
1869 const void *paths,
1870 GLuint pathBase,
1871 GLenum fillMode,
1872 GLuint mask,
1873 GLenum coverMode,
1874 GLenum transformType,
1875 const GLfloat *transformValues)
1876{
1877 const auto &pathObjects =
1878 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1879
1880 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1881 syncRendererState();
1882
1883 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1884 transformType, transformValues);
1885}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001886
Sami Väisänend59ca052016-06-21 16:10:00 +03001887void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1888 GLenum pathNameType,
1889 const void *paths,
1890 GLuint pathBase,
1891 GLint reference,
1892 GLuint mask,
1893 GLenum coverMode,
1894 GLenum transformType,
1895 const GLfloat *transformValues)
1896{
1897 const auto &pathObjects =
1898 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1899
1900 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1901 syncRendererState();
1902
1903 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1904 transformType, transformValues);
1905}
1906
Sami Väisänen46eaa942016-06-29 10:26:37 +03001907void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1908{
1909 auto *programObject = getProgram(program);
1910
1911 programObject->bindFragmentInputLocation(location, name);
1912}
1913
1914void Context::programPathFragmentInputGen(GLuint program,
1915 GLint location,
1916 GLenum genMode,
1917 GLint components,
1918 const GLfloat *coeffs)
1919{
1920 auto *programObject = getProgram(program);
1921
1922 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1923}
1924
Jamie Madill437fa652016-05-03 15:13:24 -04001925void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001926{
Geoff Langda5777c2014-07-11 09:52:58 -04001927 if (error.isError())
1928 {
1929 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001930
1931 if (!error.getMessage().empty())
1932 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001933 auto *debug = &mGLState.getDebug();
1934 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1935 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001936 }
Geoff Langda5777c2014-07-11 09:52:58 -04001937 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001938}
1939
1940// Get one of the recorded errors and clear its flag, if any.
1941// [OpenGL ES 2.0.24] section 2.5 page 13.
1942GLenum Context::getError()
1943{
Geoff Langda5777c2014-07-11 09:52:58 -04001944 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945 {
Geoff Langda5777c2014-07-11 09:52:58 -04001946 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 }
Geoff Langda5777c2014-07-11 09:52:58 -04001948 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001949 {
Geoff Langda5777c2014-07-11 09:52:58 -04001950 GLenum error = *mErrors.begin();
1951 mErrors.erase(mErrors.begin());
1952 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001954}
1955
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001956// NOTE: this function should not assume that this context is current!
1957void Context::markContextLost()
1958{
1959 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
1960 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
1961 mContextLost = true;
1962}
1963
1964bool Context::isContextLost()
1965{
1966 return mContextLost;
1967}
1968
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001969GLenum Context::getResetStatus()
1970{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001971 // Even if the application doesn't want to know about resets, we want to know
1972 // as it will allow us to skip all the calls.
1973 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001974 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001975 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001976 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001977 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001978 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001979
1980 // EXT_robustness, section 2.6: If the reset notification behavior is
1981 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1982 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1983 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 }
1985
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001986 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1987 // status should be returned at least once, and GL_NO_ERROR should be returned
1988 // once the device has finished resetting.
1989 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001990 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991 ASSERT(mResetStatus == GL_NO_ERROR);
1992 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001993
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001994 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001995 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997 }
1998 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 else if (mResetStatus != GL_NO_ERROR)
2000 {
2001 mResetStatus = mImplementation->getResetStatus();
2002 }
Jamie Madill893ab082014-05-16 16:56:10 -04002003
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002004 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005}
2006
2007bool Context::isResetNotificationEnabled()
2008{
2009 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2010}
2011
Corentin Walleze3b10e82015-05-20 11:06:25 -04002012const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002013{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002014 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002015}
2016
2017EGLenum Context::getClientType() const
2018{
2019 return mClientType;
2020}
2021
2022EGLenum Context::getRenderBuffer() const
2023{
Corentin Wallez37c39792015-08-20 14:19:46 -04002024 auto framebufferIt = mFramebufferMap.find(0);
2025 if (framebufferIt != mFramebufferMap.end())
2026 {
2027 const Framebuffer *framebuffer = framebufferIt->second;
2028 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2029
2030 ASSERT(backAttachment != nullptr);
2031 return backAttachment->getSurface()->getRenderBuffer();
2032 }
2033 else
2034 {
2035 return EGL_NONE;
2036 }
Régis Fénéon83107972015-02-05 12:57:44 +01002037}
2038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002039VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002040{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002041 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002042 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2043 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002044 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002045 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2046
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002047 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002049
2050 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002051}
2052
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002054{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002055 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002056 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2057 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002058 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002059 transformFeedback =
2060 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002061 transformFeedback->addRef();
2062 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002063 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002064
2065 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002066}
2067
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002068Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2069{
2070 // Can be called from Bind without a prior call to Gen.
2071 auto framebufferIt = mFramebufferMap.find(framebuffer);
2072 bool neverCreated = framebufferIt == mFramebufferMap.end();
2073 if (neverCreated || framebufferIt->second == nullptr)
2074 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002075 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002076 if (neverCreated)
2077 {
2078 mFramebufferHandleAllocator.reserve(framebuffer);
2079 mFramebufferMap[framebuffer] = newFBO;
2080 return newFBO;
2081 }
2082
2083 framebufferIt->second = newFBO;
2084 }
2085
2086 return framebufferIt->second;
2087}
2088
Geoff Langf41a7152016-09-19 15:11:17 -04002089bool Context::isTextureGenerated(GLuint texture) const
2090{
2091 return mResourceManager->isTextureGenerated(texture);
2092}
2093
2094bool Context::isBufferGenerated(GLuint buffer) const
2095{
2096 return mResourceManager->isBufferGenerated(buffer);
2097}
2098
2099bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2100{
2101 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2102}
2103
2104bool Context::isFramebufferGenerated(GLuint framebuffer) const
2105{
2106 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2107 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2108}
2109
Geoff Lang36167ab2015-12-07 10:27:14 -05002110bool Context::isVertexArrayGenerated(GLuint vertexArray)
2111{
Geoff Langf41a7152016-09-19 15:11:17 -04002112 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002113 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2114}
2115
2116bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2117{
Geoff Langf41a7152016-09-19 15:11:17 -04002118 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002119 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2120}
2121
Shannon Woods53a94a82014-06-24 15:20:36 -04002122void Context::detachTexture(GLuint texture)
2123{
2124 // Simple pass-through to State's detachTexture method, as textures do not require
2125 // allocation map management either here or in the resource manager at detach time.
2126 // Zero textures are held by the Context, and we don't attempt to request them from
2127 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002128 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002129}
2130
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002131void Context::detachBuffer(GLuint buffer)
2132{
Yuly Novikov5807a532015-12-03 13:01:22 -05002133 // Simple pass-through to State's detachBuffer method, since
2134 // only buffer attachments to container objects that are bound to the current context
2135 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002136
Yuly Novikov5807a532015-12-03 13:01:22 -05002137 // [OpenGL ES 3.2] section 5.1.2 page 45:
2138 // Attachments to unbound container objects, such as
2139 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2140 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002142}
2143
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002144void Context::detachFramebuffer(GLuint framebuffer)
2145{
Shannon Woods53a94a82014-06-24 15:20:36 -04002146 // Framebuffer detachment is handled by Context, because 0 is a valid
2147 // Framebuffer object, and a pointer to it must be passed from Context
2148 // to State at binding time.
2149
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 // [OpenGL ES 2.0.24] section 4.4 page 107:
2151 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2152 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2153
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002154 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 {
2156 bindReadFramebuffer(0);
2157 }
2158
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002160 {
2161 bindDrawFramebuffer(0);
2162 }
2163}
2164
2165void Context::detachRenderbuffer(GLuint renderbuffer)
2166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002167 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002168}
2169
Jamie Madill57a89722013-07-02 11:57:03 -04002170void Context::detachVertexArray(GLuint vertexArray)
2171{
Jamie Madill77a72f62015-04-14 11:18:32 -04002172 // Vertex array detachment is handled by Context, because 0 is a valid
2173 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002174 // binding time.
2175
Jamie Madill57a89722013-07-02 11:57:03 -04002176 // [OpenGL ES 3.0.2] section 2.10 page 43:
2177 // If a vertex array object that is currently bound is deleted, the binding
2178 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002179 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002180 {
2181 bindVertexArray(0);
2182 }
2183}
2184
Geoff Langc8058452014-02-03 12:04:11 -05002185void Context::detachTransformFeedback(GLuint transformFeedback)
2186{
Corentin Walleza2257da2016-04-19 16:43:12 -04002187 // Transform feedback detachment is handled by Context, because 0 is a valid
2188 // transform feedback, and a pointer to it must be passed from Context to State at
2189 // binding time.
2190
2191 // The OpenGL specification doesn't mention what should happen when the currently bound
2192 // transform feedback object is deleted. Since it is a container object, we treat it like
2193 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002194 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002195 {
2196 bindTransformFeedback(0);
2197 }
Geoff Langc8058452014-02-03 12:04:11 -05002198}
2199
Jamie Madilldc356042013-07-19 16:36:57 -04002200void Context::detachSampler(GLuint sampler)
2201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002202 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002203}
2204
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002205void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002207 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002208}
2209
Jamie Madille29d1672013-07-19 16:36:57 -04002210void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2211{
Jamie Madill901b3792016-05-26 09:20:40 -04002212 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002213
2214 Sampler *samplerObject = getSampler(sampler);
2215 ASSERT(samplerObject);
2216
Geoff Lang69cce582015-09-17 13:20:36 -04002217 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002218 switch (pname)
2219 {
Geoff Lang69cce582015-09-17 13:20:36 -04002220 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2221 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2222 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2223 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2224 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2225 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2226 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2227 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2228 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2229 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2230 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002231 }
Geoff Lang69cce582015-09-17 13:20:36 -04002232 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002233}
2234
2235void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2236{
Jamie Madill901b3792016-05-26 09:20:40 -04002237 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002238
2239 Sampler *samplerObject = getSampler(sampler);
2240 ASSERT(samplerObject);
2241
Geoff Lang69cce582015-09-17 13:20:36 -04002242 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002243 switch (pname)
2244 {
Geoff Lang69cce582015-09-17 13:20:36 -04002245 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2246 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2247 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2248 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2249 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2250 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2251 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2252 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2253 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2254 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2255 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002256 }
Geoff Lang69cce582015-09-17 13:20:36 -04002257 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002258}
2259
Jamie Madill9675b802013-07-19 16:36:59 -04002260GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2261{
Jamie Madill901b3792016-05-26 09:20:40 -04002262 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002263
2264 Sampler *samplerObject = getSampler(sampler);
2265 ASSERT(samplerObject);
2266
Geoff Lang69cce582015-09-17 13:20:36 -04002267 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002268 switch (pname)
2269 {
Geoff Lang69cce582015-09-17 13:20:36 -04002270 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2271 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2272 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2273 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2274 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2275 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002276 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2277 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002278 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2279 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2280 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002281 }
Geoff Lang69cce582015-09-17 13:20:36 -04002282 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002283}
2284
2285GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2286{
Jamie Madill901b3792016-05-26 09:20:40 -04002287 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002288
2289 Sampler *samplerObject = getSampler(sampler);
2290 ASSERT(samplerObject);
2291
Geoff Lang69cce582015-09-17 13:20:36 -04002292 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002293 switch (pname)
2294 {
Geoff Lang69cce582015-09-17 13:20:36 -04002295 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2296 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2297 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2298 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2299 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2300 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2301 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2302 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2303 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2304 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2305 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002306 }
Geoff Lang69cce582015-09-17 13:20:36 -04002307 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002308}
2309
Olli Etuahof0fee072016-03-30 15:11:58 +03002310void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2311{
2312 gl::Program *programObject = getProgram(program);
2313 ASSERT(programObject != nullptr);
2314
2315 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2316 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2317}
2318
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002319void Context::initRendererString()
2320{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002321 std::ostringstream rendererString;
2322 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002323 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002324 rendererString << ")";
2325
Geoff Langcec35902014-04-16 10:52:36 -04002326 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002327}
2328
Geoff Langc287ea62016-09-16 14:46:51 -04002329const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002330{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002331 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002332}
2333
Geoff Langcec35902014-04-16 10:52:36 -04002334void Context::initExtensionStrings()
2335{
Geoff Langc287ea62016-09-16 14:46:51 -04002336 for (const auto &extensionString : mExtensions.getStrings())
2337 {
2338 mExtensionStrings.push_back(MakeStaticString(extensionString));
2339 }
Geoff Langcec35902014-04-16 10:52:36 -04002340
Geoff Langc0b9ef42014-07-02 10:02:37 -04002341 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002342 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2343 std::ostream_iterator<const char *>(combinedStringStream, " "));
2344 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002345}
2346
Geoff Langc287ea62016-09-16 14:46:51 -04002347const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002348{
2349 return mExtensionString;
2350}
2351
Geoff Langc287ea62016-09-16 14:46:51 -04002352const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002353{
2354 return mExtensionStrings[idx];
2355}
2356
2357size_t Context::getExtensionStringCount() const
2358{
2359 return mExtensionStrings.size();
2360}
2361
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002362void Context::beginTransformFeedback(GLenum primitiveMode)
2363{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002364 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002365 ASSERT(transformFeedback != nullptr);
2366 ASSERT(!transformFeedback->isPaused());
2367
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002368 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002369}
2370
2371bool Context::hasActiveTransformFeedback(GLuint program) const
2372{
2373 for (auto pair : mTransformFeedbackMap)
2374 {
2375 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2376 {
2377 return true;
2378 }
2379 }
2380 return false;
2381}
2382
Geoff Langc287ea62016-09-16 14:46:51 -04002383void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002384{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002385 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002386
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002387 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002388
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002389 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002390
Martin Radev1be913c2016-07-11 17:59:16 +03002391 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002392 {
2393 // Disable ES3+ extensions
2394 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002395 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002396 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002397 }
2398
Martin Radev1be913c2016-07-11 17:59:16 +03002399 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002400 {
2401 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2402 //mExtensions.sRGB = false;
2403 }
2404
Jamie Madill00ed7a12016-05-19 13:13:38 -04002405 // Some extensions are always available because they are implemented in the GL layer.
2406 mExtensions.bindUniformLocation = true;
2407 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002408 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002409
2410 // Enable the no error extension if the context was created with the flag.
2411 mExtensions.noError = mSkipValidation;
2412
Geoff Lang70d0f492015-12-10 17:45:46 -05002413 // Explicitly enable GL_KHR_debug
2414 mExtensions.debug = true;
2415 mExtensions.maxDebugMessageLength = 1024;
2416 mExtensions.maxDebugLoggedMessages = 1024;
2417 mExtensions.maxDebugGroupStackDepth = 1024;
2418 mExtensions.maxLabelLength = 1024;
2419
Geoff Langff5b2d52016-09-07 11:32:23 -04002420 // Explicitly enable GL_ANGLE_robust_client_memory
2421 mExtensions.robustClientMemory = true;
2422
Geoff Lang301d1612014-07-09 10:34:37 -04002423 // Apply implementation limits
2424 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002425 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2426 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2427
2428 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002429
Geoff Langc287ea62016-09-16 14:46:51 -04002430 // WebGL compatibility
2431 mExtensions.webglCompatibility = webGLContext;
2432 for (const auto &extensionInfo : GetExtensionInfoMap())
2433 {
2434 // If this context is for WebGL, disable all enableable extensions
2435 if (webGLContext && extensionInfo.second.Enableable)
2436 {
2437 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2438 }
2439 }
2440
2441 // Generate texture caps
2442 updateCaps();
2443}
2444
2445void Context::updateCaps()
2446{
Geoff Lang900013c2014-07-07 11:32:19 -04002447 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002448 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002449
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002450 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002451 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2452 {
2453 GLenum format = i->first;
2454 TextureCaps formatCaps = i->second;
2455
Geoff Lang5d601382014-07-22 15:14:06 -04002456 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002457
Geoff Lang0d8b7242015-09-09 14:56:53 -04002458 // Update the format caps based on the client version and extensions.
2459 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2460 // ES3.
2461 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002462 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002463 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002464 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002465 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002466 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002467
2468 // OpenGL ES does not support multisampling with integer formats
2469 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002470 {
Geoff Langd87878e2014-09-19 15:42:59 -04002471 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002472 }
Geoff Langd87878e2014-09-19 15:42:59 -04002473
2474 if (formatCaps.texturable && formatInfo.compressed)
2475 {
2476 mCaps.compressedTextureFormats.push_back(format);
2477 }
2478
2479 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002480 }
2481}
2482
Jamie Madill1b94d432015-08-07 13:23:23 -04002483void Context::syncRendererState()
2484{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002485 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2486 mImplementation->syncState(mGLState, dirtyBits);
2487 mGLState.clearDirtyBits();
2488 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002489}
2490
Jamie Madillad9f24e2016-02-12 09:27:24 -05002491void Context::syncRendererState(const State::DirtyBits &bitMask,
2492 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002494 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2495 mImplementation->syncState(mGLState, dirtyBits);
2496 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002497
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002498 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002499}
Jamie Madillc29968b2016-01-20 11:17:23 -05002500
2501void Context::blitFramebuffer(GLint srcX0,
2502 GLint srcY0,
2503 GLint srcX1,
2504 GLint srcY1,
2505 GLint dstX0,
2506 GLint dstY0,
2507 GLint dstX1,
2508 GLint dstY1,
2509 GLbitfield mask,
2510 GLenum filter)
2511{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002512 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 ASSERT(drawFramebuffer);
2514
2515 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2516 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2517
Jamie Madillad9f24e2016-02-12 09:27:24 -05002518 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002519
Jamie Madill8415b5f2016-04-26 13:41:39 -04002520 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002521}
Jamie Madillc29968b2016-01-20 11:17:23 -05002522
2523void Context::clear(GLbitfield mask)
2524{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002525 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002526 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002527}
2528
2529void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2530{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002531 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002532 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2533 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002534}
2535
2536void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2537{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002538 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002539 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2540 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002541}
2542
2543void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2544{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002545 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002546 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2547 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002548}
2549
2550void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2551{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002552 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002553 ASSERT(framebufferObject);
2554
2555 // If a buffer is not present, the clear has no effect
2556 if (framebufferObject->getDepthbuffer() == nullptr &&
2557 framebufferObject->getStencilbuffer() == nullptr)
2558 {
2559 return;
2560 }
2561
Jamie Madillad9f24e2016-02-12 09:27:24 -05002562 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002563 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2564 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002565}
2566
2567void Context::readPixels(GLint x,
2568 GLint y,
2569 GLsizei width,
2570 GLsizei height,
2571 GLenum format,
2572 GLenum type,
2573 GLvoid *pixels)
2574{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002575 if (width == 0 || height == 0)
2576 {
2577 return;
2578 }
2579
Jamie Madillad9f24e2016-02-12 09:27:24 -05002580 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002581
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002582 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 ASSERT(framebufferObject);
2584
2585 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002586 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002587}
2588
2589void Context::copyTexImage2D(GLenum target,
2590 GLint level,
2591 GLenum internalformat,
2592 GLint x,
2593 GLint y,
2594 GLsizei width,
2595 GLsizei height,
2596 GLint border)
2597{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002598 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002599 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002600
Jamie Madillc29968b2016-01-20 11:17:23 -05002601 Rectangle sourceArea(x, y, width, height);
2602
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002603 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002604 Texture *texture =
2605 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002606 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002607}
2608
2609void Context::copyTexSubImage2D(GLenum target,
2610 GLint level,
2611 GLint xoffset,
2612 GLint yoffset,
2613 GLint x,
2614 GLint y,
2615 GLsizei width,
2616 GLsizei height)
2617{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002618 if (width == 0 || height == 0)
2619 {
2620 return;
2621 }
2622
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002623 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002624 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002625
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 Offset destOffset(xoffset, yoffset, 0);
2627 Rectangle sourceArea(x, y, width, height);
2628
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002629 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002630 Texture *texture =
2631 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002632 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002633}
2634
2635void Context::copyTexSubImage3D(GLenum target,
2636 GLint level,
2637 GLint xoffset,
2638 GLint yoffset,
2639 GLint zoffset,
2640 GLint x,
2641 GLint y,
2642 GLsizei width,
2643 GLsizei height)
2644{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002645 if (width == 0 || height == 0)
2646 {
2647 return;
2648 }
2649
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002650 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002651 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002652
Jamie Madillc29968b2016-01-20 11:17:23 -05002653 Offset destOffset(xoffset, yoffset, zoffset);
2654 Rectangle sourceArea(x, y, width, height);
2655
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002657 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002658 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002659}
2660
2661void Context::framebufferTexture2D(GLenum target,
2662 GLenum attachment,
2663 GLenum textarget,
2664 GLuint texture,
2665 GLint level)
2666{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002668 ASSERT(framebuffer);
2669
2670 if (texture != 0)
2671 {
2672 Texture *textureObj = getTexture(texture);
2673
2674 ImageIndex index = ImageIndex::MakeInvalid();
2675
2676 if (textarget == GL_TEXTURE_2D)
2677 {
2678 index = ImageIndex::Make2D(level);
2679 }
2680 else
2681 {
2682 ASSERT(IsCubeMapTextureTarget(textarget));
2683 index = ImageIndex::MakeCube(textarget, level);
2684 }
2685
2686 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2687 }
2688 else
2689 {
2690 framebuffer->resetAttachment(attachment);
2691 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002692
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002693 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002694}
2695
2696void Context::framebufferRenderbuffer(GLenum target,
2697 GLenum attachment,
2698 GLenum renderbuffertarget,
2699 GLuint renderbuffer)
2700{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002701 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 ASSERT(framebuffer);
2703
2704 if (renderbuffer != 0)
2705 {
2706 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2707 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2708 renderbufferObject);
2709 }
2710 else
2711 {
2712 framebuffer->resetAttachment(attachment);
2713 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002714
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002715 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002716}
2717
2718void Context::framebufferTextureLayer(GLenum target,
2719 GLenum attachment,
2720 GLuint texture,
2721 GLint level,
2722 GLint layer)
2723{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002724 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002725 ASSERT(framebuffer);
2726
2727 if (texture != 0)
2728 {
2729 Texture *textureObject = getTexture(texture);
2730
2731 ImageIndex index = ImageIndex::MakeInvalid();
2732
2733 if (textureObject->getTarget() == GL_TEXTURE_3D)
2734 {
2735 index = ImageIndex::Make3D(level, layer);
2736 }
2737 else
2738 {
2739 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2740 index = ImageIndex::Make2DArray(level, layer);
2741 }
2742
2743 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2744 }
2745 else
2746 {
2747 framebuffer->resetAttachment(attachment);
2748 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002749
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002750 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002751}
2752
2753void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2754{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002756 ASSERT(framebuffer);
2757 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002758 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002759}
2760
2761void Context::readBuffer(GLenum mode)
2762{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002764 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002766}
2767
2768void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2769{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002770 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002771 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002772
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 ASSERT(framebuffer);
2775
2776 // The specification isn't clear what should be done when the framebuffer isn't complete.
2777 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002778 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002779}
2780
2781void Context::invalidateFramebuffer(GLenum target,
2782 GLsizei numAttachments,
2783 const GLenum *attachments)
2784{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002785 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002787
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002788 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002789 ASSERT(framebuffer);
2790
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002792 {
Jamie Madill437fa652016-05-03 15:13:24 -04002793 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002794 }
Jamie Madill437fa652016-05-03 15:13:24 -04002795
2796 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002797}
2798
2799void Context::invalidateSubFramebuffer(GLenum target,
2800 GLsizei numAttachments,
2801 const GLenum *attachments,
2802 GLint x,
2803 GLint y,
2804 GLsizei width,
2805 GLsizei height)
2806{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002807 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002809
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002811 ASSERT(framebuffer);
2812
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002814 {
Jamie Madill437fa652016-05-03 15:13:24 -04002815 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002816 }
Jamie Madill437fa652016-05-03 15:13:24 -04002817
2818 Rectangle area(x, y, width, height);
2819 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002820}
2821
Jamie Madill73a84962016-02-12 09:27:23 -05002822void Context::texImage2D(GLenum target,
2823 GLint level,
2824 GLint internalformat,
2825 GLsizei width,
2826 GLsizei height,
2827 GLint border,
2828 GLenum format,
2829 GLenum type,
2830 const GLvoid *pixels)
2831{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002832 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002833
2834 Extents size(width, height, 1);
2835 Texture *texture =
2836 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002838 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002839}
2840
2841void Context::texImage3D(GLenum target,
2842 GLint level,
2843 GLint internalformat,
2844 GLsizei width,
2845 GLsizei height,
2846 GLsizei depth,
2847 GLint border,
2848 GLenum format,
2849 GLenum type,
2850 const GLvoid *pixels)
2851{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002852 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002853
2854 Extents size(width, height, depth);
2855 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002856 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002857 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002858}
2859
2860void Context::texSubImage2D(GLenum target,
2861 GLint level,
2862 GLint xoffset,
2863 GLint yoffset,
2864 GLsizei width,
2865 GLsizei height,
2866 GLenum format,
2867 GLenum type,
2868 const GLvoid *pixels)
2869{
2870 // Zero sized uploads are valid but no-ops
2871 if (width == 0 || height == 0)
2872 {
2873 return;
2874 }
2875
Jamie Madillad9f24e2016-02-12 09:27:24 -05002876 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002877
2878 Box area(xoffset, yoffset, 0, width, height, 1);
2879 Texture *texture =
2880 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002881 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002882 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002883}
2884
2885void Context::texSubImage3D(GLenum target,
2886 GLint level,
2887 GLint xoffset,
2888 GLint yoffset,
2889 GLint zoffset,
2890 GLsizei width,
2891 GLsizei height,
2892 GLsizei depth,
2893 GLenum format,
2894 GLenum type,
2895 const GLvoid *pixels)
2896{
2897 // Zero sized uploads are valid but no-ops
2898 if (width == 0 || height == 0 || depth == 0)
2899 {
2900 return;
2901 }
2902
Jamie Madillad9f24e2016-02-12 09:27:24 -05002903 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002904
2905 Box area(xoffset, yoffset, zoffset, width, height, depth);
2906 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002907 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002908 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002909}
2910
2911void Context::compressedTexImage2D(GLenum target,
2912 GLint level,
2913 GLenum internalformat,
2914 GLsizei width,
2915 GLsizei height,
2916 GLint border,
2917 GLsizei imageSize,
2918 const GLvoid *data)
2919{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002920 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002921
2922 Extents size(width, height, 1);
2923 Texture *texture =
2924 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002925 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2926 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002927 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002928}
2929
2930void Context::compressedTexImage3D(GLenum target,
2931 GLint level,
2932 GLenum internalformat,
2933 GLsizei width,
2934 GLsizei height,
2935 GLsizei depth,
2936 GLint border,
2937 GLsizei imageSize,
2938 const GLvoid *data)
2939{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002940 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002941
2942 Extents size(width, height, depth);
2943 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002944 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2945 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002946 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002947}
2948
2949void Context::compressedTexSubImage2D(GLenum target,
2950 GLint level,
2951 GLint xoffset,
2952 GLint yoffset,
2953 GLsizei width,
2954 GLsizei height,
2955 GLenum format,
2956 GLsizei imageSize,
2957 const GLvoid *data)
2958{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002959 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002960
2961 Box area(xoffset, yoffset, 0, width, height, 1);
2962 Texture *texture =
2963 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002964 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2965 format, imageSize,
2966 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002967}
2968
2969void Context::compressedTexSubImage3D(GLenum target,
2970 GLint level,
2971 GLint xoffset,
2972 GLint yoffset,
2973 GLint zoffset,
2974 GLsizei width,
2975 GLsizei height,
2976 GLsizei depth,
2977 GLenum format,
2978 GLsizei imageSize,
2979 const GLvoid *data)
2980{
2981 // Zero sized uploads are valid but no-ops
2982 if (width == 0 || height == 0)
2983 {
2984 return;
2985 }
2986
Jamie Madillad9f24e2016-02-12 09:27:24 -05002987 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002988
2989 Box area(xoffset, yoffset, zoffset, width, height, depth);
2990 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002991 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2992 format, imageSize,
2993 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002994}
2995
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002996void Context::generateMipmap(GLenum target)
2997{
2998 Texture *texture = getTargetTexture(target);
2999 handleError(texture->generateMipmap());
3000}
3001
Geoff Langc287ea62016-09-16 14:46:51 -04003002GLboolean Context::enableExtension(const char *name)
3003{
3004 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
3005 ASSERT(extensionInfos.find(name) != extensionInfos.end());
3006 const auto &extension = extensionInfos.at(name);
3007 ASSERT(extension.Enableable);
3008
3009 if (mExtensions.*(extension.ExtensionsMember))
3010 {
3011 // Extension already enabled
3012 return GL_TRUE;
3013 }
3014
3015 const auto &nativeExtensions = mImplementation->getNativeExtensions();
3016 if (!(nativeExtensions.*(extension.ExtensionsMember)))
3017 {
3018 // Underlying implementation does not support this valid extension
3019 return GL_FALSE;
3020 }
3021
3022 mExtensions.*(extension.ExtensionsMember) = true;
3023 updateCaps();
3024 initExtensionStrings();
3025 return GL_TRUE;
3026}
3027
Geoff Lang97073d12016-04-20 10:42:34 -07003028void Context::copyTextureCHROMIUM(GLuint sourceId,
3029 GLuint destId,
3030 GLint internalFormat,
3031 GLenum destType,
3032 GLboolean unpackFlipY,
3033 GLboolean unpackPremultiplyAlpha,
3034 GLboolean unpackUnmultiplyAlpha)
3035{
3036 syncStateForTexImage();
3037
3038 gl::Texture *sourceTexture = getTexture(sourceId);
3039 gl::Texture *destTexture = getTexture(destId);
3040 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3041 unpackPremultiplyAlpha == GL_TRUE,
3042 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3043}
3044
3045void Context::copySubTextureCHROMIUM(GLuint sourceId,
3046 GLuint destId,
3047 GLint xoffset,
3048 GLint yoffset,
3049 GLint x,
3050 GLint y,
3051 GLsizei width,
3052 GLsizei height,
3053 GLboolean unpackFlipY,
3054 GLboolean unpackPremultiplyAlpha,
3055 GLboolean unpackUnmultiplyAlpha)
3056{
3057 // Zero sized copies are valid but no-ops
3058 if (width == 0 || height == 0)
3059 {
3060 return;
3061 }
3062
3063 syncStateForTexImage();
3064
3065 gl::Texture *sourceTexture = getTexture(sourceId);
3066 gl::Texture *destTexture = getTexture(destId);
3067 Offset offset(xoffset, yoffset, 0);
3068 Rectangle area(x, y, width, height);
3069 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3070 unpackPremultiplyAlpha == GL_TRUE,
3071 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3072}
3073
Geoff Lang47110bf2016-04-20 11:13:22 -07003074void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3075{
3076 syncStateForTexImage();
3077
3078 gl::Texture *sourceTexture = getTexture(sourceId);
3079 gl::Texture *destTexture = getTexture(destId);
3080 handleError(destTexture->copyCompressedTexture(sourceTexture));
3081}
3082
Olli Etuaho4f667482016-03-30 15:56:35 +03003083void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3084{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003085 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003086 ASSERT(buffer);
3087
3088 if (!buffer->isMapped())
3089 {
3090 *params = nullptr;
3091 }
3092 else
3093 {
3094 *params = buffer->getMapPointer();
3095 }
3096}
3097
3098GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3099{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003101 ASSERT(buffer);
3102
3103 Error error = buffer->map(access);
3104 if (error.isError())
3105 {
Jamie Madill437fa652016-05-03 15:13:24 -04003106 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003107 return nullptr;
3108 }
3109
3110 return buffer->getMapPointer();
3111}
3112
3113GLboolean Context::unmapBuffer(GLenum target)
3114{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116 ASSERT(buffer);
3117
3118 GLboolean result;
3119 Error error = buffer->unmap(&result);
3120 if (error.isError())
3121 {
Jamie Madill437fa652016-05-03 15:13:24 -04003122 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003123 return GL_FALSE;
3124 }
3125
3126 return result;
3127}
3128
3129GLvoid *Context::mapBufferRange(GLenum target,
3130 GLintptr offset,
3131 GLsizeiptr length,
3132 GLbitfield access)
3133{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003135 ASSERT(buffer);
3136
3137 Error error = buffer->mapRange(offset, length, access);
3138 if (error.isError())
3139 {
Jamie Madill437fa652016-05-03 15:13:24 -04003140 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003141 return nullptr;
3142 }
3143
3144 return buffer->getMapPointer();
3145}
3146
3147void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3148{
3149 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3150}
3151
Jamie Madillad9f24e2016-02-12 09:27:24 -05003152void Context::syncStateForReadPixels()
3153{
3154 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3155}
3156
3157void Context::syncStateForTexImage()
3158{
3159 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3160}
3161
3162void Context::syncStateForClear()
3163{
3164 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3165}
3166
3167void Context::syncStateForBlit()
3168{
3169 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3170}
3171
Jamie Madillc20ab272016-06-09 07:20:46 -07003172void Context::activeTexture(GLenum texture)
3173{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003174 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003175}
3176
3177void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3178{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003180}
3181
3182void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3183{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003184 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003185}
3186
3187void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3188{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003190}
3191
3192void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3193{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003195}
3196
3197void Context::clearDepthf(GLclampf depth)
3198{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003199 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003200}
3201
3202void Context::clearStencil(GLint s)
3203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003204 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003205}
3206
3207void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3208{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003209 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003210}
3211
3212void Context::cullFace(GLenum mode)
3213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003214 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003215}
3216
3217void Context::depthFunc(GLenum func)
3218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003220}
3221
3222void Context::depthMask(GLboolean flag)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::disable(GLenum cap)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::disableVertexAttribArray(GLuint index)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::enable(GLenum cap)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::enableVertexAttribArray(GLuint index)
3248{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250}
3251
3252void Context::frontFace(GLenum mode)
3253{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255}
3256
3257void Context::hint(GLenum target, GLenum mode)
3258{
3259 switch (target)
3260 {
3261 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003263 break;
3264
3265 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003267 break;
3268
3269 default:
3270 UNREACHABLE();
3271 return;
3272 }
3273}
3274
3275void Context::lineWidth(GLfloat width)
3276{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278}
3279
3280void Context::pixelStorei(GLenum pname, GLint param)
3281{
3282 switch (pname)
3283 {
3284 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003285 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003286 break;
3287
3288 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003290 break;
3291
3292 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003293 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003294 break;
3295
3296 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003297 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003298 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003299 break;
3300
3301 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003302 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003303 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003304 break;
3305
3306 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003307 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003308 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003309 break;
3310
3311 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003312 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314 break;
3315
3316 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003317 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 break;
3320
3321 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003322 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003323 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003324 break;
3325
3326 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003327 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003329 break;
3330
3331 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003332 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 break;
3335
3336 default:
3337 UNREACHABLE();
3338 return;
3339 }
3340}
3341
3342void Context::polygonOffset(GLfloat factor, GLfloat units)
3343{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003344 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003345}
3346
3347void Context::sampleCoverage(GLclampf value, GLboolean invert)
3348{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003349 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003350}
3351
3352void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3353{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003354 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003355}
3356
3357void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3358{
3359 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3360 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003361 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003362 }
3363
3364 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3365 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003366 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003367 }
3368}
3369
3370void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3371{
3372 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3373 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375 }
3376
3377 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3378 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380 }
3381}
3382
3383void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3384{
3385 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3386 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003387 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003388 }
3389
3390 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3391 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003392 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003393 }
3394}
3395
3396void Context::vertexAttrib1f(GLuint index, GLfloat x)
3397{
3398 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400}
3401
3402void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3403{
3404 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003405 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003406}
3407
3408void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3409{
3410 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003412}
3413
3414void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3415{
3416 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003418}
3419
3420void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3421{
3422 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003424}
3425
3426void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3427{
3428 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3433{
3434 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003435 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003436}
3437
3438void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3439{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003440 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003441}
3442
3443void Context::vertexAttribPointer(GLuint index,
3444 GLint size,
3445 GLenum type,
3446 GLboolean normalized,
3447 GLsizei stride,
3448 const GLvoid *ptr)
3449{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003450 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3451 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3455{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003456 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::vertexAttribIPointer(GLuint index,
3460 GLint size,
3461 GLenum type,
3462 GLsizei stride,
3463 const GLvoid *pointer)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3466 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003467}
3468
3469void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3470{
3471 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003472 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003473}
3474
3475void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3476{
3477 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003478 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003479}
3480
3481void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3482{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003483 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003484}
3485
3486void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3487{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003488 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003489}
3490
3491void Context::debugMessageControl(GLenum source,
3492 GLenum type,
3493 GLenum severity,
3494 GLsizei count,
3495 const GLuint *ids,
3496 GLboolean enabled)
3497{
3498 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003499 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3500 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003501}
3502
3503void Context::debugMessageInsert(GLenum source,
3504 GLenum type,
3505 GLuint id,
3506 GLenum severity,
3507 GLsizei length,
3508 const GLchar *buf)
3509{
3510 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003511 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003512}
3513
3514void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3515{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003516 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003517}
3518
3519GLuint Context::getDebugMessageLog(GLuint count,
3520 GLsizei bufSize,
3521 GLenum *sources,
3522 GLenum *types,
3523 GLuint *ids,
3524 GLenum *severities,
3525 GLsizei *lengths,
3526 GLchar *messageLog)
3527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003528 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3529 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003530}
3531
3532void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3533{
3534 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003535 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003536}
3537
3538void Context::popDebugGroup()
3539{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003540 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003541}
3542
Jamie Madill29639852016-09-02 15:00:09 -04003543void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3544{
3545 Buffer *buffer = mGLState.getTargetBuffer(target);
3546 ASSERT(buffer);
3547 handleError(buffer->bufferData(target, data, size, usage));
3548}
3549
3550void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3551{
3552 if (data == nullptr)
3553 {
3554 return;
3555 }
3556
3557 Buffer *buffer = mGLState.getTargetBuffer(target);
3558 ASSERT(buffer);
3559 handleError(buffer->bufferSubData(target, data, size, offset));
3560}
3561
Jamie Madillc29968b2016-01-20 11:17:23 -05003562} // namespace gl