blob: 1ed648cc1690ac15f0e31eb66cbaa2d3d6de910d [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 Lang301d1612014-07-09 10:34:37 -04002420 // Apply implementation limits
2421 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002422 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2423 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2424
2425 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002426
Geoff Langc287ea62016-09-16 14:46:51 -04002427 // WebGL compatibility
2428 mExtensions.webglCompatibility = webGLContext;
2429 for (const auto &extensionInfo : GetExtensionInfoMap())
2430 {
2431 // If this context is for WebGL, disable all enableable extensions
2432 if (webGLContext && extensionInfo.second.Enableable)
2433 {
2434 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2435 }
2436 }
2437
2438 // Generate texture caps
2439 updateCaps();
2440}
2441
2442void Context::updateCaps()
2443{
Geoff Lang900013c2014-07-07 11:32:19 -04002444 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002445 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002446
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002447 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002448 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2449 {
2450 GLenum format = i->first;
2451 TextureCaps formatCaps = i->second;
2452
Geoff Lang5d601382014-07-22 15:14:06 -04002453 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002454
Geoff Lang0d8b7242015-09-09 14:56:53 -04002455 // Update the format caps based on the client version and extensions.
2456 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2457 // ES3.
2458 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002459 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002460 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002461 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002462 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002463 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002464
2465 // OpenGL ES does not support multisampling with integer formats
2466 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002467 {
Geoff Langd87878e2014-09-19 15:42:59 -04002468 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002469 }
Geoff Langd87878e2014-09-19 15:42:59 -04002470
2471 if (formatCaps.texturable && formatInfo.compressed)
2472 {
2473 mCaps.compressedTextureFormats.push_back(format);
2474 }
2475
2476 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002477 }
2478}
2479
Jamie Madill1b94d432015-08-07 13:23:23 -04002480void Context::syncRendererState()
2481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002482 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2483 mImplementation->syncState(mGLState, dirtyBits);
2484 mGLState.clearDirtyBits();
2485 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002486}
2487
Jamie Madillad9f24e2016-02-12 09:27:24 -05002488void Context::syncRendererState(const State::DirtyBits &bitMask,
2489 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002490{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002491 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2492 mImplementation->syncState(mGLState, dirtyBits);
2493 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002494
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002495 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002496}
Jamie Madillc29968b2016-01-20 11:17:23 -05002497
2498void Context::blitFramebuffer(GLint srcX0,
2499 GLint srcY0,
2500 GLint srcX1,
2501 GLint srcY1,
2502 GLint dstX0,
2503 GLint dstY0,
2504 GLint dstX1,
2505 GLint dstY1,
2506 GLbitfield mask,
2507 GLenum filter)
2508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002509 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002510 ASSERT(drawFramebuffer);
2511
2512 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2513 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2514
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
Jamie Madill8415b5f2016-04-26 13:41:39 -04002517 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002518}
Jamie Madillc29968b2016-01-20 11:17:23 -05002519
2520void Context::clear(GLbitfield mask)
2521{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002522 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002523 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002524}
2525
2526void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2527{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002528 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002529 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2530 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002531}
2532
2533void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2534{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002535 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002536 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2537 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002538}
2539
2540void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2541{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002542 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002543 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2544 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002545}
2546
2547void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2548{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002549 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002550 ASSERT(framebufferObject);
2551
2552 // If a buffer is not present, the clear has no effect
2553 if (framebufferObject->getDepthbuffer() == nullptr &&
2554 framebufferObject->getStencilbuffer() == nullptr)
2555 {
2556 return;
2557 }
2558
Jamie Madillad9f24e2016-02-12 09:27:24 -05002559 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002560 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2561 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002562}
2563
2564void Context::readPixels(GLint x,
2565 GLint y,
2566 GLsizei width,
2567 GLsizei height,
2568 GLenum format,
2569 GLenum type,
2570 GLvoid *pixels)
2571{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002572 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002573
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002574 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 ASSERT(framebufferObject);
2576
2577 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002578 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002579}
2580
2581void Context::copyTexImage2D(GLenum target,
2582 GLint level,
2583 GLenum internalformat,
2584 GLint x,
2585 GLint y,
2586 GLsizei width,
2587 GLsizei height,
2588 GLint border)
2589{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002590 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002591 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002592
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 Rectangle sourceArea(x, y, width, height);
2594
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002595 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 Texture *texture =
2597 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002598 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002599}
2600
2601void Context::copyTexSubImage2D(GLenum target,
2602 GLint level,
2603 GLint xoffset,
2604 GLint yoffset,
2605 GLint x,
2606 GLint y,
2607 GLsizei width,
2608 GLsizei height)
2609{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002610 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002611 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002612
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 Offset destOffset(xoffset, yoffset, 0);
2614 Rectangle sourceArea(x, y, width, height);
2615
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002616 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002617 Texture *texture =
2618 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002619 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002620}
2621
2622void Context::copyTexSubImage3D(GLenum target,
2623 GLint level,
2624 GLint xoffset,
2625 GLint yoffset,
2626 GLint zoffset,
2627 GLint x,
2628 GLint y,
2629 GLsizei width,
2630 GLsizei height)
2631{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002632 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002633 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002634
Jamie Madillc29968b2016-01-20 11:17:23 -05002635 Offset destOffset(xoffset, yoffset, zoffset);
2636 Rectangle sourceArea(x, y, width, height);
2637
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002638 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002639 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002640 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002641}
2642
2643void Context::framebufferTexture2D(GLenum target,
2644 GLenum attachment,
2645 GLenum textarget,
2646 GLuint texture,
2647 GLint level)
2648{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002649 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 ASSERT(framebuffer);
2651
2652 if (texture != 0)
2653 {
2654 Texture *textureObj = getTexture(texture);
2655
2656 ImageIndex index = ImageIndex::MakeInvalid();
2657
2658 if (textarget == GL_TEXTURE_2D)
2659 {
2660 index = ImageIndex::Make2D(level);
2661 }
2662 else
2663 {
2664 ASSERT(IsCubeMapTextureTarget(textarget));
2665 index = ImageIndex::MakeCube(textarget, level);
2666 }
2667
2668 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2669 }
2670 else
2671 {
2672 framebuffer->resetAttachment(attachment);
2673 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002674
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002675 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002676}
2677
2678void Context::framebufferRenderbuffer(GLenum target,
2679 GLenum attachment,
2680 GLenum renderbuffertarget,
2681 GLuint renderbuffer)
2682{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 ASSERT(framebuffer);
2685
2686 if (renderbuffer != 0)
2687 {
2688 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2689 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2690 renderbufferObject);
2691 }
2692 else
2693 {
2694 framebuffer->resetAttachment(attachment);
2695 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002696
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002697 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002698}
2699
2700void Context::framebufferTextureLayer(GLenum target,
2701 GLenum attachment,
2702 GLuint texture,
2703 GLint level,
2704 GLint layer)
2705{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002706 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002707 ASSERT(framebuffer);
2708
2709 if (texture != 0)
2710 {
2711 Texture *textureObject = getTexture(texture);
2712
2713 ImageIndex index = ImageIndex::MakeInvalid();
2714
2715 if (textureObject->getTarget() == GL_TEXTURE_3D)
2716 {
2717 index = ImageIndex::Make3D(level, layer);
2718 }
2719 else
2720 {
2721 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2722 index = ImageIndex::Make2DArray(level, layer);
2723 }
2724
2725 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2726 }
2727 else
2728 {
2729 framebuffer->resetAttachment(attachment);
2730 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002731
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002732 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002733}
2734
2735void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2736{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002737 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002738 ASSERT(framebuffer);
2739 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002740 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002741}
2742
2743void Context::readBuffer(GLenum mode)
2744{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002745 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002746 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002748}
2749
2750void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2751{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002752 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002753 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002754
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002756 ASSERT(framebuffer);
2757
2758 // The specification isn't clear what should be done when the framebuffer isn't complete.
2759 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002760 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002761}
2762
2763void Context::invalidateFramebuffer(GLenum target,
2764 GLsizei numAttachments,
2765 const GLenum *attachments)
2766{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002767 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002769
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002770 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002771 ASSERT(framebuffer);
2772
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002774 {
Jamie Madill437fa652016-05-03 15:13:24 -04002775 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002776 }
Jamie Madill437fa652016-05-03 15:13:24 -04002777
2778 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002779}
2780
2781void Context::invalidateSubFramebuffer(GLenum target,
2782 GLsizei numAttachments,
2783 const GLenum *attachments,
2784 GLint x,
2785 GLint y,
2786 GLsizei width,
2787 GLsizei height)
2788{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002789 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002791
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002793 ASSERT(framebuffer);
2794
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002795 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002796 {
Jamie Madill437fa652016-05-03 15:13:24 -04002797 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002798 }
Jamie Madill437fa652016-05-03 15:13:24 -04002799
2800 Rectangle area(x, y, width, height);
2801 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002802}
2803
Jamie Madill73a84962016-02-12 09:27:23 -05002804void Context::texImage2D(GLenum target,
2805 GLint level,
2806 GLint internalformat,
2807 GLsizei width,
2808 GLsizei height,
2809 GLint border,
2810 GLenum format,
2811 GLenum type,
2812 const GLvoid *pixels)
2813{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002814 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002815
2816 Extents size(width, height, 1);
2817 Texture *texture =
2818 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002820 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002821}
2822
2823void Context::texImage3D(GLenum target,
2824 GLint level,
2825 GLint internalformat,
2826 GLsizei width,
2827 GLsizei height,
2828 GLsizei depth,
2829 GLint border,
2830 GLenum format,
2831 GLenum type,
2832 const GLvoid *pixels)
2833{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002834 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002835
2836 Extents size(width, height, depth);
2837 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002838 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002839 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002840}
2841
2842void Context::texSubImage2D(GLenum target,
2843 GLint level,
2844 GLint xoffset,
2845 GLint yoffset,
2846 GLsizei width,
2847 GLsizei height,
2848 GLenum format,
2849 GLenum type,
2850 const GLvoid *pixels)
2851{
2852 // Zero sized uploads are valid but no-ops
2853 if (width == 0 || height == 0)
2854 {
2855 return;
2856 }
2857
Jamie Madillad9f24e2016-02-12 09:27:24 -05002858 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002859
2860 Box area(xoffset, yoffset, 0, width, height, 1);
2861 Texture *texture =
2862 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002864 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002865}
2866
2867void Context::texSubImage3D(GLenum target,
2868 GLint level,
2869 GLint xoffset,
2870 GLint yoffset,
2871 GLint zoffset,
2872 GLsizei width,
2873 GLsizei height,
2874 GLsizei depth,
2875 GLenum format,
2876 GLenum type,
2877 const GLvoid *pixels)
2878{
2879 // Zero sized uploads are valid but no-ops
2880 if (width == 0 || height == 0 || depth == 0)
2881 {
2882 return;
2883 }
2884
Jamie Madillad9f24e2016-02-12 09:27:24 -05002885 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002886
2887 Box area(xoffset, yoffset, zoffset, width, height, depth);
2888 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002889 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002890 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002891}
2892
2893void Context::compressedTexImage2D(GLenum target,
2894 GLint level,
2895 GLenum internalformat,
2896 GLsizei width,
2897 GLsizei height,
2898 GLint border,
2899 GLsizei imageSize,
2900 const GLvoid *data)
2901{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002902 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002903
2904 Extents size(width, height, 1);
2905 Texture *texture =
2906 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002907 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2908 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002909 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002910}
2911
2912void Context::compressedTexImage3D(GLenum target,
2913 GLint level,
2914 GLenum internalformat,
2915 GLsizei width,
2916 GLsizei height,
2917 GLsizei depth,
2918 GLint border,
2919 GLsizei imageSize,
2920 const GLvoid *data)
2921{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002922 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002923
2924 Extents size(width, height, depth);
2925 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002926 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2927 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002928 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002929}
2930
2931void Context::compressedTexSubImage2D(GLenum target,
2932 GLint level,
2933 GLint xoffset,
2934 GLint yoffset,
2935 GLsizei width,
2936 GLsizei height,
2937 GLenum format,
2938 GLsizei imageSize,
2939 const GLvoid *data)
2940{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002941 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002942
2943 Box area(xoffset, yoffset, 0, width, height, 1);
2944 Texture *texture =
2945 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002946 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2947 format, imageSize,
2948 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002949}
2950
2951void Context::compressedTexSubImage3D(GLenum target,
2952 GLint level,
2953 GLint xoffset,
2954 GLint yoffset,
2955 GLint zoffset,
2956 GLsizei width,
2957 GLsizei height,
2958 GLsizei depth,
2959 GLenum format,
2960 GLsizei imageSize,
2961 const GLvoid *data)
2962{
2963 // Zero sized uploads are valid but no-ops
2964 if (width == 0 || height == 0)
2965 {
2966 return;
2967 }
2968
Jamie Madillad9f24e2016-02-12 09:27:24 -05002969 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002970
2971 Box area(xoffset, yoffset, zoffset, width, height, depth);
2972 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002973 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2974 format, imageSize,
2975 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002976}
2977
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002978void Context::generateMipmap(GLenum target)
2979{
2980 Texture *texture = getTargetTexture(target);
2981 handleError(texture->generateMipmap());
2982}
2983
Geoff Langc287ea62016-09-16 14:46:51 -04002984GLboolean Context::enableExtension(const char *name)
2985{
2986 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2987 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2988 const auto &extension = extensionInfos.at(name);
2989 ASSERT(extension.Enableable);
2990
2991 if (mExtensions.*(extension.ExtensionsMember))
2992 {
2993 // Extension already enabled
2994 return GL_TRUE;
2995 }
2996
2997 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2998 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2999 {
3000 // Underlying implementation does not support this valid extension
3001 return GL_FALSE;
3002 }
3003
3004 mExtensions.*(extension.ExtensionsMember) = true;
3005 updateCaps();
3006 initExtensionStrings();
3007 return GL_TRUE;
3008}
3009
Geoff Lang97073d12016-04-20 10:42:34 -07003010void Context::copyTextureCHROMIUM(GLuint sourceId,
3011 GLuint destId,
3012 GLint internalFormat,
3013 GLenum destType,
3014 GLboolean unpackFlipY,
3015 GLboolean unpackPremultiplyAlpha,
3016 GLboolean unpackUnmultiplyAlpha)
3017{
3018 syncStateForTexImage();
3019
3020 gl::Texture *sourceTexture = getTexture(sourceId);
3021 gl::Texture *destTexture = getTexture(destId);
3022 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
3023 unpackPremultiplyAlpha == GL_TRUE,
3024 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3025}
3026
3027void Context::copySubTextureCHROMIUM(GLuint sourceId,
3028 GLuint destId,
3029 GLint xoffset,
3030 GLint yoffset,
3031 GLint x,
3032 GLint y,
3033 GLsizei width,
3034 GLsizei height,
3035 GLboolean unpackFlipY,
3036 GLboolean unpackPremultiplyAlpha,
3037 GLboolean unpackUnmultiplyAlpha)
3038{
3039 // Zero sized copies are valid but no-ops
3040 if (width == 0 || height == 0)
3041 {
3042 return;
3043 }
3044
3045 syncStateForTexImage();
3046
3047 gl::Texture *sourceTexture = getTexture(sourceId);
3048 gl::Texture *destTexture = getTexture(destId);
3049 Offset offset(xoffset, yoffset, 0);
3050 Rectangle area(x, y, width, height);
3051 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3052 unpackPremultiplyAlpha == GL_TRUE,
3053 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3054}
3055
Olli Etuaho4f667482016-03-30 15:56:35 +03003056void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
3057{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003059 ASSERT(buffer);
3060
3061 if (!buffer->isMapped())
3062 {
3063 *params = nullptr;
3064 }
3065 else
3066 {
3067 *params = buffer->getMapPointer();
3068 }
3069}
3070
3071GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3072{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003073 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003074 ASSERT(buffer);
3075
3076 Error error = buffer->map(access);
3077 if (error.isError())
3078 {
Jamie Madill437fa652016-05-03 15:13:24 -04003079 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003080 return nullptr;
3081 }
3082
3083 return buffer->getMapPointer();
3084}
3085
3086GLboolean Context::unmapBuffer(GLenum target)
3087{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003088 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003089 ASSERT(buffer);
3090
3091 GLboolean result;
3092 Error error = buffer->unmap(&result);
3093 if (error.isError())
3094 {
Jamie Madill437fa652016-05-03 15:13:24 -04003095 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003096 return GL_FALSE;
3097 }
3098
3099 return result;
3100}
3101
3102GLvoid *Context::mapBufferRange(GLenum target,
3103 GLintptr offset,
3104 GLsizeiptr length,
3105 GLbitfield access)
3106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003107 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003108 ASSERT(buffer);
3109
3110 Error error = buffer->mapRange(offset, length, access);
3111 if (error.isError())
3112 {
Jamie Madill437fa652016-05-03 15:13:24 -04003113 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003114 return nullptr;
3115 }
3116
3117 return buffer->getMapPointer();
3118}
3119
3120void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3121{
3122 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3123}
3124
Jamie Madillad9f24e2016-02-12 09:27:24 -05003125void Context::syncStateForReadPixels()
3126{
3127 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3128}
3129
3130void Context::syncStateForTexImage()
3131{
3132 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3133}
3134
3135void Context::syncStateForClear()
3136{
3137 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3138}
3139
3140void Context::syncStateForBlit()
3141{
3142 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3143}
3144
Jamie Madillc20ab272016-06-09 07:20:46 -07003145void Context::activeTexture(GLenum texture)
3146{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003147 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003148}
3149
3150void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3151{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003153}
3154
3155void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3156{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003157 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003158}
3159
3160void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3161{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003162 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003163}
3164
3165void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003168}
3169
3170void Context::clearDepthf(GLclampf depth)
3171{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003172 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003173}
3174
3175void Context::clearStencil(GLint s)
3176{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003177 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003178}
3179
3180void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3181{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003182 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003183}
3184
3185void Context::cullFace(GLenum mode)
3186{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003187 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003188}
3189
3190void Context::depthFunc(GLenum func)
3191{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003192 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003193}
3194
3195void Context::depthMask(GLboolean flag)
3196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003197 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003198}
3199
3200void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003202 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003203}
3204
3205void Context::disable(GLenum cap)
3206{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003207 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003208}
3209
3210void Context::disableVertexAttribArray(GLuint index)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
3215void Context::enable(GLenum cap)
3216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003217 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003218}
3219
3220void Context::enableVertexAttribArray(GLuint index)
3221{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003222 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003223}
3224
3225void Context::frontFace(GLenum mode)
3226{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003227 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003228}
3229
3230void Context::hint(GLenum target, GLenum mode)
3231{
3232 switch (target)
3233 {
3234 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236 break;
3237
3238 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240 break;
3241
3242 default:
3243 UNREACHABLE();
3244 return;
3245 }
3246}
3247
3248void Context::lineWidth(GLfloat width)
3249{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003250 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003251}
3252
3253void Context::pixelStorei(GLenum pname, GLint param)
3254{
3255 switch (pname)
3256 {
3257 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003258 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003259 break;
3260
3261 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003262 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003263 break;
3264
3265 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003266 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003267 break;
3268
3269 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003270 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003271 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003272 break;
3273
3274 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003275 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003276 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003277 break;
3278
3279 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003280 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003281 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003282 break;
3283
3284 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003285 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003286 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003287 break;
3288
3289 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003290 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292 break;
3293
3294 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003295 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003296 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003297 break;
3298
3299 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003300 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302 break;
3303
3304 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003305 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003306 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003307 break;
3308
3309 default:
3310 UNREACHABLE();
3311 return;
3312 }
3313}
3314
3315void Context::polygonOffset(GLfloat factor, GLfloat units)
3316{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003317 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003318}
3319
3320void Context::sampleCoverage(GLclampf value, GLboolean invert)
3321{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003322 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003323}
3324
3325void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3326{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003327 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003328}
3329
3330void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3331{
3332 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3333 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003334 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003335 }
3336
3337 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3338 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003339 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003340 }
3341}
3342
3343void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3344{
3345 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3346 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003347 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003348 }
3349
3350 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3351 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003352 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003353 }
3354}
3355
3356void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3357{
3358 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3359 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003360 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003361 }
3362
3363 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3364 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003365 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003366 }
3367}
3368
3369void Context::vertexAttrib1f(GLuint index, GLfloat x)
3370{
3371 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003372 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003373}
3374
3375void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3376{
3377 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003378 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003379}
3380
3381void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3382{
3383 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003384 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003385}
3386
3387void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3388{
3389 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003390 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003391}
3392
3393void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3394{
3395 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003397}
3398
3399void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3400{
3401 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003402 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003403}
3404
3405void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3406{
3407 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003408 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003409}
3410
3411void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3412{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003413 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003414}
3415
3416void Context::vertexAttribPointer(GLuint index,
3417 GLint size,
3418 GLenum type,
3419 GLboolean normalized,
3420 GLsizei stride,
3421 const GLvoid *ptr)
3422{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003423 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3424 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3428{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::vertexAttribIPointer(GLuint index,
3433 GLint size,
3434 GLenum type,
3435 GLsizei stride,
3436 const GLvoid *pointer)
3437{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003438 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3439 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003440}
3441
3442void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3443{
3444 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003446}
3447
3448void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3449{
3450 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003451 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003452}
3453
3454void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3455{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003456 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003457}
3458
3459void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3460{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003461 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003462}
3463
3464void Context::debugMessageControl(GLenum source,
3465 GLenum type,
3466 GLenum severity,
3467 GLsizei count,
3468 const GLuint *ids,
3469 GLboolean enabled)
3470{
3471 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003472 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3473 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003474}
3475
3476void Context::debugMessageInsert(GLenum source,
3477 GLenum type,
3478 GLuint id,
3479 GLenum severity,
3480 GLsizei length,
3481 const GLchar *buf)
3482{
3483 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003484 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003485}
3486
3487void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3488{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003489 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003490}
3491
3492GLuint Context::getDebugMessageLog(GLuint count,
3493 GLsizei bufSize,
3494 GLenum *sources,
3495 GLenum *types,
3496 GLuint *ids,
3497 GLenum *severities,
3498 GLsizei *lengths,
3499 GLchar *messageLog)
3500{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003501 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3502 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003503}
3504
3505void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3506{
3507 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::popDebugGroup()
3512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
Jamie Madill29639852016-09-02 15:00:09 -04003516void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3517{
3518 Buffer *buffer = mGLState.getTargetBuffer(target);
3519 ASSERT(buffer);
3520 handleError(buffer->bufferData(target, data, size, usage));
3521}
3522
3523void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3524{
3525 if (data == nullptr)
3526 {
3527 return;
3528 }
3529
3530 Buffer *buffer = mGLState.getTargetBuffer(target);
3531 ASSERT(buffer);
3532 handleError(buffer->bufferSubData(target, data, size, offset));
3533}
3534
Jamie Madillc29968b2016-01-20 11:17:23 -05003535} // namespace gl