blob: e0c45b5266dc5f9ced102bf7bfc6a691f83d52e9 [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"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000040
Geoff Langf6db0982015-08-25 13:04:00 -040041namespace
42{
43
Ian Ewell3ffd78b2016-01-22 16:09:42 -050044template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030045std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
46 GLsizei numPaths,
47 const void *paths,
48 GLuint pathBase)
49{
50 std::vector<gl::Path *> ret;
51 ret.reserve(numPaths);
52
53 const auto *nameArray = static_cast<const T *>(paths);
54
55 for (GLsizei i = 0; i < numPaths; ++i)
56 {
57 const GLuint pathName = nameArray[i] + pathBase;
58
59 ret.push_back(resourceManager.getPath(pathName));
60 }
61
62 return ret;
63}
64
65std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
66 GLsizei numPaths,
67 GLenum pathNameType,
68 const void *paths,
69 GLuint pathBase)
70{
71 switch (pathNameType)
72 {
73 case GL_UNSIGNED_BYTE:
74 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
75
76 case GL_BYTE:
77 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_UNSIGNED_SHORT:
80 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_SHORT:
83 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_UNSIGNED_INT:
86 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_INT:
89 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
90 }
91
92 UNREACHABLE();
93 return std::vector<gl::Path *>();
94}
95
96template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050097gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
98{
99 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
100 ASSERT(queryObject != nullptr);
101
102 switch (pname)
103 {
104 case GL_QUERY_RESULT_EXT:
105 return queryObject->getResult(params);
106 case GL_QUERY_RESULT_AVAILABLE_EXT:
107 {
108 bool available;
109 gl::Error error = queryObject->isResultAvailable(&available);
110 if (!error.isError())
111 {
112 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
113 }
114 return error;
115 }
116 default:
117 UNREACHABLE();
118 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
119 }
120}
121
Geoff Langf6db0982015-08-25 13:04:00 -0400122void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
123{
Geoff Lang1a683462015-09-29 15:09:59 -0400124 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400125 {
126 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
127 tfBufferIndex++)
128 {
129 const OffsetBindingPointer<gl::Buffer> &buffer =
130 transformFeedback->getIndexedBuffer(tfBufferIndex);
131 if (buffer.get() != nullptr)
132 {
133 buffer->onTransformFeedback();
134 }
135 }
136 }
137}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138
139// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300140EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400142 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143}
144
Martin Radev1be913c2016-07-11 17:59:16 +0300145EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
146{
147 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
148}
149
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500150GLenum GetResetStrategy(const egl::AttributeMap &attribs)
151{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400152 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
153 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500154 switch (attrib)
155 {
156 case EGL_NO_RESET_NOTIFICATION:
157 return GL_NO_RESET_NOTIFICATION_EXT;
158 case EGL_LOSE_CONTEXT_ON_RESET:
159 return GL_LOSE_CONTEXT_ON_RESET_EXT;
160 default:
161 UNREACHABLE();
162 return GL_NONE;
163 }
164}
165
166bool GetRobustAccess(const egl::AttributeMap &attribs)
167{
168 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
169}
170
171bool GetDebug(const egl::AttributeMap &attribs)
172{
173 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
174}
175
176bool GetNoError(const egl::AttributeMap &attribs)
177{
178 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
179}
180
Martin Radev9d901792016-07-15 15:58:58 +0300181std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
182{
183 std::string labelName;
184 if (label != nullptr)
185 {
186 size_t labelLength = length < 0 ? strlen(label) : length;
187 labelName = std::string(label, labelLength);
188 }
189 return labelName;
190}
191
192void GetObjectLabelBase(const std::string &objectLabel,
193 GLsizei bufSize,
194 GLsizei *length,
195 GLchar *label)
196{
197 size_t writeLength = objectLabel.length();
198 if (label != nullptr && bufSize > 0)
199 {
200 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
201 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
202 label[writeLength] = '\0';
203 }
204
205 if (length != nullptr)
206 {
207 *length = static_cast<GLsizei>(writeLength);
208 }
209}
210
Geoff Langf6db0982015-08-25 13:04:00 -0400211} // anonymous namespace
212
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000213namespace gl
214{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000215
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400216Context::Context(rx::EGLImplFactory *implFactory,
217 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400218 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500219 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300220
221 : ValidationContext(GetClientMajorVersion(attribs),
222 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700223 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500224 mCaps,
225 mTextureCaps,
226 mExtensions,
227 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500228 mLimitations,
229 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700230 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500231 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300232 mClientMajorVersion(GetClientMajorVersion(attribs)),
233 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400234 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500235 mClientType(EGL_OPENGL_ES_API),
236 mHasBeenCurrent(false),
237 mContextLost(false),
238 mResetStatus(GL_NO_ERROR),
239 mResetStrategy(GetResetStrategy(attribs)),
240 mRobustAccess(GetRobustAccess(attribs)),
241 mCurrentSurface(nullptr),
242 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000243{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500244 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000245
Jamie Madill00ed7a12016-05-19 13:13:38 -0400246 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400247
Martin Radev1be913c2016-07-11 17:59:16 +0300248 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100249
Shannon Woods53a94a82014-06-24 15:20:36 -0400250 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400251
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400252 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000253 {
254 mResourceManager = shareContext->mResourceManager;
255 mResourceManager->addRef();
256 }
257 else
258 {
Jamie Madill901b3792016-05-26 09:20:40 -0400259 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000260 }
261
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700262 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400263
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000264 // [OpenGL ES 2.0.24] section 3.7 page 83:
265 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
266 // and cube map texture state vectors respectively associated with them.
267 // In order that access to these initial textures not be lost, they are treated as texture
268 // objects all of whose names are 0.
269
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400270 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500271 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500272
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400273 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500274 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400275
Martin Radev1be913c2016-07-11 17:59:16 +0300276 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400277 {
278 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400279 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500280 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400281
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400282 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500283 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400284 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285
Ian Ewellbda75592016-04-18 17:25:54 -0400286 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
287 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400288 Texture *zeroTextureExternal =
289 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400290 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
291 }
292
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700293 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500294
Jamie Madill57a89722013-07-02 11:57:03 -0400295 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000296 bindArrayBuffer(0);
297 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400298
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000299 bindRenderbuffer(0);
300
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000301 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400302 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000303 {
304 bindIndexedUniformBuffer(0, i, 0, -1);
305 }
306
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000307 bindCopyReadBuffer(0);
308 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000309 bindPixelPackBuffer(0);
310 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000311
Martin Radev1be913c2016-07-11 17:59:16 +0300312 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400313 {
314 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
315 // In the initial state, a default transform feedback object is bound and treated as
316 // a transform feedback object with a name of zero. That object is bound any time
317 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400318 bindTransformFeedback(0);
319 }
Geoff Langc8058452014-02-03 12:04:11 -0500320
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700321 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500322
323 // Initialize dirty bit masks
324 // TODO(jmadill): additional ES3 state
325 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
326 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
327 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
328 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
329 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
330 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400331 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500332 // No dirty objects.
333
334 // Readpixels uses the pack state and read FBO
335 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
336 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
337 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
338 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
339 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400340 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500341 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
342
343 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
344 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
345 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
346 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
347 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
348 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
349 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
350 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
351 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
352 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
353 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
354 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
355
356 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
357 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
358 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
359 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400360
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400361 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000362}
363
364Context::~Context()
365{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700366 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000367
Corentin Wallez37c39792015-08-20 14:19:46 -0400368 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000369 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400370 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400371 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400372 {
373 SafeDelete(framebuffer.second);
374 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000375 }
376
Corentin Wallez80b24112015-08-25 16:41:57 -0400377 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000378 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400379 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000380 }
381
Corentin Wallez80b24112015-08-25 16:41:57 -0400382 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000383 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400384 if (query.second != nullptr)
385 {
386 query.second->release();
387 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000388 }
389
Corentin Wallez80b24112015-08-25 16:41:57 -0400390 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400391 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400392 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400393 }
394
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500396 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500397 if (transformFeedback.second != nullptr)
398 {
399 transformFeedback.second->release();
400 }
Geoff Langc8058452014-02-03 12:04:11 -0500401 }
402
Jamie Madilldedd7b92014-11-05 16:30:36 -0500403 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400404 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500405 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400406 }
407 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408
Corentin Wallez51706ea2015-08-07 14:39:22 -0400409 if (mCurrentSurface != nullptr)
410 {
411 releaseSurface();
412 }
413
Jamie Madill1e9ae072014-11-06 15:27:21 -0500414 if (mResourceManager)
415 {
416 mResourceManager->release();
417 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500418
419 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
daniel@transgaming.comad629872012-11-28 19:32:06 +0000422void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423{
Jamie Madill77a72f62015-04-14 11:18:32 -0400424 ASSERT(surface != nullptr);
425
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426 if (!mHasBeenCurrent)
427 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000428 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400429 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000430
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700431 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
432 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433
434 mHasBeenCurrent = true;
435 }
436
Jamie Madill1b94d432015-08-07 13:23:23 -0400437 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700438 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400439
Corentin Wallez51706ea2015-08-07 14:39:22 -0400440 if (mCurrentSurface)
441 {
442 releaseSurface();
443 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000444 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400445 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000446
Corentin Wallez37c39792015-08-20 14:19:46 -0400447 // Update default framebuffer, the binding of the previous default
448 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400449 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400450 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700451 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400452 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700453 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400454 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700455 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400456 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700457 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400458 }
459 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400460 }
Ian Ewell292f0052016-02-04 10:37:32 -0500461
462 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700463 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000464}
465
Jamie Madill77a72f62015-04-14 11:18:32 -0400466void Context::releaseSurface()
467{
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 ASSERT(mCurrentSurface != nullptr);
469
470 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400471 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700473 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700475 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400476 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700477 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400478 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700479 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400480 }
481 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400482 }
483
Corentin Wallez51706ea2015-08-07 14:39:22 -0400484 mCurrentSurface->setIsCurrent(false);
485 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400486}
487
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000488// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000489void Context::markContextLost()
490{
491 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
492 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
493 mContextLost = true;
494}
495
496bool Context::isContextLost()
497{
498 return mContextLost;
499}
500
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000501GLuint Context::createBuffer()
502{
503 return mResourceManager->createBuffer();
504}
505
506GLuint Context::createProgram()
507{
Jamie Madill901b3792016-05-26 09:20:40 -0400508 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000509}
510
511GLuint Context::createShader(GLenum type)
512{
Jamie Madill901b3792016-05-26 09:20:40 -0400513 return mResourceManager->createShader(mImplementation.get(),
514 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000515}
516
517GLuint Context::createTexture()
518{
519 return mResourceManager->createTexture();
520}
521
522GLuint Context::createRenderbuffer()
523{
524 return mResourceManager->createRenderbuffer();
525}
526
Geoff Lang882033e2014-09-30 11:26:07 -0400527GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400528{
Jamie Madill901b3792016-05-26 09:20:40 -0400529 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400530
Cooper Partind8e62a32015-01-29 15:21:25 -0800531 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400532}
533
Sami Väisänene45e53b2016-05-25 10:36:04 +0300534GLuint Context::createPaths(GLsizei range)
535{
536 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
537 if (resultOrError.isError())
538 {
539 handleError(resultOrError.getError());
540 return 0;
541 }
542 return resultOrError.getResult();
543}
544
Jamie Madill57a89722013-07-02 11:57:03 -0400545GLuint Context::createVertexArray()
546{
Geoff Lang36167ab2015-12-07 10:27:14 -0500547 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
548 mVertexArrayMap[vertexArray] = nullptr;
549 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400550}
551
Jamie Madilldc356042013-07-19 16:36:57 -0400552GLuint Context::createSampler()
553{
554 return mResourceManager->createSampler();
555}
556
Geoff Langc8058452014-02-03 12:04:11 -0500557GLuint Context::createTransformFeedback()
558{
Geoff Lang36167ab2015-12-07 10:27:14 -0500559 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
560 mTransformFeedbackMap[transformFeedback] = nullptr;
561 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500562}
563
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000564// Returns an unused framebuffer name
565GLuint Context::createFramebuffer()
566{
567 GLuint handle = mFramebufferHandleAllocator.allocate();
568
569 mFramebufferMap[handle] = NULL;
570
571 return handle;
572}
573
Jamie Madill33dc8432013-07-26 11:55:05 -0400574GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575{
Jamie Madill33dc8432013-07-26 11:55:05 -0400576 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400578 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579
580 return handle;
581}
582
583// Returns an unused query name
584GLuint Context::createQuery()
585{
586 GLuint handle = mQueryHandleAllocator.allocate();
587
588 mQueryMap[handle] = NULL;
589
590 return handle;
591}
592
593void Context::deleteBuffer(GLuint buffer)
594{
595 if (mResourceManager->getBuffer(buffer))
596 {
597 detachBuffer(buffer);
598 }
Jamie Madill893ab082014-05-16 16:56:10 -0400599
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600 mResourceManager->deleteBuffer(buffer);
601}
602
603void Context::deleteShader(GLuint shader)
604{
605 mResourceManager->deleteShader(shader);
606}
607
608void Context::deleteProgram(GLuint program)
609{
610 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000611}
612
613void Context::deleteTexture(GLuint texture)
614{
615 if (mResourceManager->getTexture(texture))
616 {
617 detachTexture(texture);
618 }
619
620 mResourceManager->deleteTexture(texture);
621}
622
623void Context::deleteRenderbuffer(GLuint renderbuffer)
624{
625 if (mResourceManager->getRenderbuffer(renderbuffer))
626 {
627 detachRenderbuffer(renderbuffer);
628 }
Jamie Madill893ab082014-05-16 16:56:10 -0400629
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630 mResourceManager->deleteRenderbuffer(renderbuffer);
631}
632
Jamie Madillcd055f82013-07-26 11:55:15 -0400633void Context::deleteFenceSync(GLsync fenceSync)
634{
635 // The spec specifies the underlying Fence object is not deleted until all current
636 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
637 // and since our API is currently designed for being called from a single thread, we can delete
638 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700639 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400640}
641
Sami Väisänene45e53b2016-05-25 10:36:04 +0300642void Context::deletePaths(GLuint first, GLsizei range)
643{
644 mResourceManager->deletePaths(first, range);
645}
646
647bool Context::hasPathData(GLuint path) const
648{
649 const auto *pathObj = mResourceManager->getPath(path);
650 if (pathObj == nullptr)
651 return false;
652
653 return pathObj->hasPathData();
654}
655
656bool Context::hasPath(GLuint path) const
657{
658 return mResourceManager->hasPath(path);
659}
660
661void Context::setPathCommands(GLuint path,
662 GLsizei numCommands,
663 const GLubyte *commands,
664 GLsizei numCoords,
665 GLenum coordType,
666 const void *coords)
667{
668 auto *pathObject = mResourceManager->getPath(path);
669
670 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
671}
672
673void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
674{
675 auto *pathObj = mResourceManager->getPath(path);
676
677 switch (pname)
678 {
679 case GL_PATH_STROKE_WIDTH_CHROMIUM:
680 pathObj->setStrokeWidth(value);
681 break;
682 case GL_PATH_END_CAPS_CHROMIUM:
683 pathObj->setEndCaps(static_cast<GLenum>(value));
684 break;
685 case GL_PATH_JOIN_STYLE_CHROMIUM:
686 pathObj->setJoinStyle(static_cast<GLenum>(value));
687 break;
688 case GL_PATH_MITER_LIMIT_CHROMIUM:
689 pathObj->setMiterLimit(value);
690 break;
691 case GL_PATH_STROKE_BOUND_CHROMIUM:
692 pathObj->setStrokeBound(value);
693 break;
694 default:
695 UNREACHABLE();
696 break;
697 }
698}
699
700void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
701{
702 const auto *pathObj = mResourceManager->getPath(path);
703
704 switch (pname)
705 {
706 case GL_PATH_STROKE_WIDTH_CHROMIUM:
707 *value = pathObj->getStrokeWidth();
708 break;
709 case GL_PATH_END_CAPS_CHROMIUM:
710 *value = static_cast<GLfloat>(pathObj->getEndCaps());
711 break;
712 case GL_PATH_JOIN_STYLE_CHROMIUM:
713 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
714 break;
715 case GL_PATH_MITER_LIMIT_CHROMIUM:
716 *value = pathObj->getMiterLimit();
717 break;
718 case GL_PATH_STROKE_BOUND_CHROMIUM:
719 *value = pathObj->getStrokeBound();
720 break;
721 default:
722 UNREACHABLE();
723 break;
724 }
725}
726
727void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
728{
729 mGLState.setPathStencilFunc(func, ref, mask);
730}
731
Jamie Madill57a89722013-07-02 11:57:03 -0400732void Context::deleteVertexArray(GLuint vertexArray)
733{
Geoff Lang36167ab2015-12-07 10:27:14 -0500734 auto iter = mVertexArrayMap.find(vertexArray);
735 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000736 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500737 VertexArray *vertexArrayObject = iter->second;
738 if (vertexArrayObject != nullptr)
739 {
740 detachVertexArray(vertexArray);
741 delete vertexArrayObject;
742 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000743
Geoff Lang36167ab2015-12-07 10:27:14 -0500744 mVertexArrayMap.erase(iter);
745 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400746 }
747}
748
Jamie Madilldc356042013-07-19 16:36:57 -0400749void Context::deleteSampler(GLuint sampler)
750{
751 if (mResourceManager->getSampler(sampler))
752 {
753 detachSampler(sampler);
754 }
755
756 mResourceManager->deleteSampler(sampler);
757}
758
Geoff Langc8058452014-02-03 12:04:11 -0500759void Context::deleteTransformFeedback(GLuint transformFeedback)
760{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500761 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500762 if (iter != mTransformFeedbackMap.end())
763 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500764 TransformFeedback *transformFeedbackObject = iter->second;
765 if (transformFeedbackObject != nullptr)
766 {
767 detachTransformFeedback(transformFeedback);
768 transformFeedbackObject->release();
769 }
770
Geoff Lang50b3fe82015-12-08 14:49:12 +0000771 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500772 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500773 }
774}
775
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000776void Context::deleteFramebuffer(GLuint framebuffer)
777{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500778 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779
780 if (framebufferObject != mFramebufferMap.end())
781 {
782 detachFramebuffer(framebuffer);
783
784 mFramebufferHandleAllocator.release(framebufferObject->first);
785 delete framebufferObject->second;
786 mFramebufferMap.erase(framebufferObject);
787 }
788}
789
Jamie Madill33dc8432013-07-26 11:55:05 -0400790void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500792 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793
Jamie Madill33dc8432013-07-26 11:55:05 -0400794 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400796 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400798 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799 }
800}
801
802void Context::deleteQuery(GLuint query)
803{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500804 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805 if (queryObject != mQueryMap.end())
806 {
807 mQueryHandleAllocator.release(queryObject->first);
808 if (queryObject->second)
809 {
810 queryObject->second->release();
811 }
812 mQueryMap.erase(queryObject);
813 }
814}
815
Geoff Lang70d0f492015-12-10 17:45:46 -0500816Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817{
818 return mResourceManager->getBuffer(handle);
819}
820
Geoff Lang48dcae72014-02-05 16:28:24 -0500821Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822{
823 return mResourceManager->getShader(handle);
824}
825
Geoff Lang48dcae72014-02-05 16:28:24 -0500826Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827{
828 return mResourceManager->getProgram(handle);
829}
830
Jamie Madill570f7c82014-07-03 10:38:54 -0400831Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832{
833 return mResourceManager->getTexture(handle);
834}
835
Geoff Lang70d0f492015-12-10 17:45:46 -0500836Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837{
838 return mResourceManager->getRenderbuffer(handle);
839}
840
Jamie Madillcd055f82013-07-26 11:55:15 -0400841FenceSync *Context::getFenceSync(GLsync handle) const
842{
Minmin Gong794e0002015-04-07 18:31:54 -0700843 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400844}
845
Jamie Madill57a89722013-07-02 11:57:03 -0400846VertexArray *Context::getVertexArray(GLuint handle) const
847{
848 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500849 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400850}
851
Jamie Madilldc356042013-07-19 16:36:57 -0400852Sampler *Context::getSampler(GLuint handle) const
853{
854 return mResourceManager->getSampler(handle);
855}
856
Geoff Langc8058452014-02-03 12:04:11 -0500857TransformFeedback *Context::getTransformFeedback(GLuint handle) const
858{
Geoff Lang36167ab2015-12-07 10:27:14 -0500859 auto iter = mTransformFeedbackMap.find(handle);
860 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500861}
862
Geoff Lang70d0f492015-12-10 17:45:46 -0500863LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
864{
865 switch (identifier)
866 {
867 case GL_BUFFER:
868 return getBuffer(name);
869 case GL_SHADER:
870 return getShader(name);
871 case GL_PROGRAM:
872 return getProgram(name);
873 case GL_VERTEX_ARRAY:
874 return getVertexArray(name);
875 case GL_QUERY:
876 return getQuery(name);
877 case GL_TRANSFORM_FEEDBACK:
878 return getTransformFeedback(name);
879 case GL_SAMPLER:
880 return getSampler(name);
881 case GL_TEXTURE:
882 return getTexture(name);
883 case GL_RENDERBUFFER:
884 return getRenderbuffer(name);
885 case GL_FRAMEBUFFER:
886 return getFramebuffer(name);
887 default:
888 UNREACHABLE();
889 return nullptr;
890 }
891}
892
893LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
894{
895 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
896}
897
Martin Radev9d901792016-07-15 15:58:58 +0300898void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
899{
900 LabeledObject *object = getLabeledObject(identifier, name);
901 ASSERT(object != nullptr);
902
903 std::string labelName = GetObjectLabelFromPointer(length, label);
904 object->setLabel(labelName);
905}
906
907void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
908{
909 LabeledObject *object = getLabeledObjectFromPtr(ptr);
910 ASSERT(object != nullptr);
911
912 std::string labelName = GetObjectLabelFromPointer(length, label);
913 object->setLabel(labelName);
914}
915
916void Context::getObjectLabel(GLenum identifier,
917 GLuint name,
918 GLsizei bufSize,
919 GLsizei *length,
920 GLchar *label) const
921{
922 LabeledObject *object = getLabeledObject(identifier, name);
923 ASSERT(object != nullptr);
924
925 const std::string &objectLabel = object->getLabel();
926 GetObjectLabelBase(objectLabel, bufSize, length, label);
927}
928
929void Context::getObjectPtrLabel(const void *ptr,
930 GLsizei bufSize,
931 GLsizei *length,
932 GLchar *label) const
933{
934 LabeledObject *object = getLabeledObjectFromPtr(ptr);
935 ASSERT(object != nullptr);
936
937 const std::string &objectLabel = object->getLabel();
938 GetObjectLabelBase(objectLabel, bufSize, length, label);
939}
940
Jamie Madilldc356042013-07-19 16:36:57 -0400941bool Context::isSampler(GLuint samplerName) const
942{
943 return mResourceManager->isSampler(samplerName);
944}
945
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500946void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947{
Jamie Madill901b3792016-05-26 09:20:40 -0400948 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700949 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953{
Jamie Madill901b3792016-05-26 09:20:40 -0400954 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700955 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Jamie Madilldedd7b92014-11-05 16:30:36 -0500958void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500960 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000961
Jamie Madilldedd7b92014-11-05 16:30:36 -0500962 if (handle == 0)
963 {
964 texture = mZeroTextures[target].get();
965 }
966 else
967 {
Jamie Madill901b3792016-05-26 09:20:40 -0400968 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969 }
970
971 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000973}
974
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500975void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500977 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700978 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000979}
980
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500981void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000982{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500983 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700984 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985}
986
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988{
Jamie Madill901b3792016-05-26 09:20:40 -0400989 Renderbuffer *renderbuffer =
990 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700991 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992}
993
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500994void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400995{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500996 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001001{
Geoff Lang76b10c92014-09-05 16:28:14 -04001002 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001003 Sampler *sampler =
1004 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001005 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001006}
1007
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001008void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001009{
Jamie Madill901b3792016-05-26 09:20:40 -04001010 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001011 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012}
1013
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001014void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1015 GLuint index,
1016 GLintptr offset,
1017 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001018{
Jamie Madill901b3792016-05-26 09:20:40 -04001019 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001020 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021}
1022
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001023void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001024{
Jamie Madill901b3792016-05-26 09:20:40 -04001025 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001026 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001027}
1028
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001029void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1030 GLuint index,
1031 GLintptr offset,
1032 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001033{
Jamie Madill901b3792016-05-26 09:20:40 -04001034 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001039{
Jamie Madill901b3792016-05-26 09:20:40 -04001040 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001042}
1043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001045{
Jamie Madill901b3792016-05-26 09:20:40 -04001046 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001047 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001048}
1049
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001050void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001051{
Jamie Madill901b3792016-05-26 09:20:40 -04001052 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001053 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001054}
1055
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001056void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001057{
Jamie Madill901b3792016-05-26 09:20:40 -04001058 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001059 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001060}
1061
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001062void Context::useProgram(GLuint program)
1063{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001064 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001065}
1066
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001067void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001068{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001069 TransformFeedback *transformFeedback =
1070 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001071 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001072}
1073
Geoff Lang5aad9672014-09-08 11:10:42 -04001074Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001075{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001077 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078
Geoff Lang5aad9672014-09-08 11:10:42 -04001079 // begin query
1080 Error error = queryObject->begin();
1081 if (error.isError())
1082 {
1083 return error;
1084 }
1085
1086 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001087 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090}
1091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001094 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001095 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096
Geoff Lang5aad9672014-09-08 11:10:42 -04001097 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098
Geoff Lang5aad9672014-09-08 11:10:42 -04001099 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001100 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001101
1102 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103}
1104
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001105Error Context::queryCounter(GLuint id, GLenum target)
1106{
1107 ASSERT(target == GL_TIMESTAMP_EXT);
1108
1109 Query *queryObject = getQuery(id, true, target);
1110 ASSERT(queryObject);
1111
1112 return queryObject->queryCounter();
1113}
1114
1115void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1116{
1117 switch (pname)
1118 {
1119 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001120 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001121 break;
1122 case GL_QUERY_COUNTER_BITS_EXT:
1123 switch (target)
1124 {
1125 case GL_TIME_ELAPSED_EXT:
1126 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1127 break;
1128 case GL_TIMESTAMP_EXT:
1129 params[0] = getExtensions().queryCounterBitsTimestamp;
1130 break;
1131 default:
1132 UNREACHABLE();
1133 params[0] = 0;
1134 break;
1135 }
1136 break;
1137 default:
1138 UNREACHABLE();
1139 return;
1140 }
1141}
1142
1143Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1144{
1145 return GetQueryObjectParameter(this, id, pname, params);
1146}
1147
1148Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1149{
1150 return GetQueryObjectParameter(this, id, pname, params);
1151}
1152
1153Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1154{
1155 return GetQueryObjectParameter(this, id, pname, params);
1156}
1157
1158Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1159{
1160 return GetQueryObjectParameter(this, id, pname, params);
1161}
1162
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001163Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001165 auto framebufferIt = mFramebufferMap.find(handle);
1166 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167}
1168
Jamie Madill33dc8432013-07-26 11:55:05 -04001169FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001171 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172
Jamie Madill33dc8432013-07-26 11:55:05 -04001173 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174 {
1175 return NULL;
1176 }
1177 else
1178 {
1179 return fence->second;
1180 }
1181}
1182
1183Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1184{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001185 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186
1187 if (query == mQueryMap.end())
1188 {
1189 return NULL;
1190 }
1191 else
1192 {
1193 if (!query->second && create)
1194 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001195 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001196 query->second->addRef();
1197 }
1198 return query->second;
1199 }
1200}
1201
Geoff Lang70d0f492015-12-10 17:45:46 -05001202Query *Context::getQuery(GLuint handle) const
1203{
1204 auto iter = mQueryMap.find(handle);
1205 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1206}
1207
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001208Texture *Context::getTargetTexture(GLenum target) const
1209{
Ian Ewellbda75592016-04-18 17:25:54 -04001210 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001211 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001212}
1213
Geoff Lang76b10c92014-09-05 16:28:14 -04001214Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001215{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001216 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217}
1218
Geoff Lang492a7e42014-11-05 13:27:06 -05001219Compiler *Context::getCompiler() const
1220{
1221 return mCompiler;
1222}
1223
Jamie Madill893ab082014-05-16 16:56:10 -04001224void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
1226 switch (pname)
1227 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001228 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001229 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001231 mGLState.getBooleanv(pname, params);
1232 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234}
1235
Jamie Madill893ab082014-05-16 16:56:10 -04001236void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237{
Shannon Woods53a94a82014-06-24 15:20:36 -04001238 // Queries about context capabilities and maximums are answered by Context.
1239 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 switch (pname)
1241 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001243 params[0] = mCaps.minAliasedLineWidth;
1244 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 break;
1246 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001247 params[0] = mCaps.minAliasedPointSize;
1248 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001249 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001250 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001251 ASSERT(mExtensions.textureFilterAnisotropic);
1252 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001253 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001254 case GL_MAX_TEXTURE_LOD_BIAS:
1255 *params = mCaps.maxLODBias;
1256 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001257
1258 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1259 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1260 {
1261 ASSERT(mExtensions.pathRendering);
1262 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1263 memcpy(params, m, 16 * sizeof(GLfloat));
1264 }
1265 break;
1266
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001268 mGLState.getFloatv(pname, params);
1269 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271}
1272
Jamie Madill893ab082014-05-16 16:56:10 -04001273void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274{
Shannon Woods53a94a82014-06-24 15:20:36 -04001275 // Queries about context capabilities and maximums are answered by Context.
1276 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001277
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278 switch (pname)
1279 {
Geoff Lang301d1612014-07-09 10:34:37 -04001280 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1281 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1282 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001283 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1284 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1285 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001286 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1287 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1288 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001289 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001290 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1291 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1292 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001293 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001294 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001295 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1296 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1297 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1298 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001299 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1300 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001301 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1302 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001303 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001304 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1305 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1306 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1307 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001308 case GL_MAJOR_VERSION:
1309 *params = mClientMajorVersion;
1310 break;
1311 case GL_MINOR_VERSION:
1312 *params = mClientMinorVersion;
1313 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001314 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1315 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001316 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1317 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1318 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001319 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1320 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1321 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001322 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001323 case GL_MAX_VIEWPORT_DIMS:
1324 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001325 params[0] = mCaps.maxViewportWidth;
1326 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327 }
1328 break;
1329 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001330 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1333 *params = mResetStrategy;
1334 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001335 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001336 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001338 case GL_SHADER_BINARY_FORMATS:
1339 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1340 break;
1341 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001342 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001343 break;
1344 case GL_PROGRAM_BINARY_FORMATS:
1345 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001347 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001348 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001349 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001350
1351 // GL_KHR_debug
1352 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1353 *params = mExtensions.maxDebugMessageLength;
1354 break;
1355 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1356 *params = mExtensions.maxDebugLoggedMessages;
1357 break;
1358 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1359 *params = mExtensions.maxDebugGroupStackDepth;
1360 break;
1361 case GL_MAX_LABEL_LENGTH:
1362 *params = mExtensions.maxLabelLength;
1363 break;
1364
Ian Ewell53f59f42016-01-28 17:36:55 -05001365 // GL_EXT_disjoint_timer_query
1366 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001367 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001368 break;
1369
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001370 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001371 mGLState.getIntegerv(mState, pname, params);
1372 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001373 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001374}
1375
Jamie Madill893ab082014-05-16 16:56:10 -04001376void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001377{
Shannon Woods53a94a82014-06-24 15:20:36 -04001378 // Queries about context capabilities and maximums are answered by Context.
1379 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001380 switch (pname)
1381 {
1382 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001383 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001384 break;
1385 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001386 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001387 break;
1388 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001389 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001390 break;
1391 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001392 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001393 break;
1394 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001395 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001396 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001397
1398 // GL_EXT_disjoint_timer_query
1399 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001400 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001401 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001402 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001403 UNREACHABLE();
1404 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001405 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001406}
1407
Geoff Lang70d0f492015-12-10 17:45:46 -05001408void Context::getPointerv(GLenum pname, void **params) const
1409{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001410 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001411}
1412
Shannon Woods1b2fb852013-08-19 14:28:48 -04001413bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1414{
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 // Queries about context capabilities and maximums are answered by Context.
1416 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001417 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001418 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001419 return mGLState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001420}
1421
1422bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1423{
Shannon Woods53a94a82014-06-24 15:20:36 -04001424 // Queries about context capabilities and maximums are answered by Context.
1425 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001426 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001427 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001428 return mGLState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001429}
1430
Geoff Langf6db0982015-08-25 13:04:00 -04001431Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001432{
Jamie Madill1b94d432015-08-07 13:23:23 -04001433 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001434 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001435 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001436
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001437 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001438}
1439
Geoff Langf6db0982015-08-25 13:04:00 -04001440Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1441{
1442 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001443 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001444 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001445
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001446 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001447}
1448
1449Error Context::drawElements(GLenum mode,
1450 GLsizei count,
1451 GLenum type,
1452 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001453 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001454{
Jamie Madill1b94d432015-08-07 13:23:23 -04001455 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001456 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001457}
1458
1459Error Context::drawElementsInstanced(GLenum mode,
1460 GLsizei count,
1461 GLenum type,
1462 const GLvoid *indices,
1463 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001464 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001465{
1466 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001467 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1468 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001469}
1470
1471Error Context::drawRangeElements(GLenum mode,
1472 GLuint start,
1473 GLuint end,
1474 GLsizei count,
1475 GLenum type,
1476 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001477 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001478{
1479 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001480 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001481}
1482
Geoff Lang129753a2015-01-09 16:52:09 -05001483Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001485 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001486}
1487
1488Error Context::finish()
1489{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001490 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491}
1492
Austin Kinross6ee1e782015-05-29 17:05:37 -07001493void Context::insertEventMarker(GLsizei length, const char *marker)
1494{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001495 ASSERT(mImplementation);
1496 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001497}
1498
1499void Context::pushGroupMarker(GLsizei length, const char *marker)
1500{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001501 ASSERT(mImplementation);
1502 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001503}
1504
1505void Context::popGroupMarker()
1506{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001507 ASSERT(mImplementation);
1508 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001509}
1510
Geoff Langd8605522016-04-13 10:19:12 -04001511void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1512{
1513 Program *programObject = getProgram(program);
1514 ASSERT(programObject);
1515
1516 programObject->bindUniformLocation(location, name);
1517}
1518
Sami Väisänena797e062016-05-12 15:23:40 +03001519void Context::setCoverageModulation(GLenum components)
1520{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001521 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001522}
1523
Sami Väisänene45e53b2016-05-25 10:36:04 +03001524void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1525{
1526 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1527}
1528
1529void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1530{
1531 GLfloat I[16];
1532 angle::Matrix<GLfloat>::setToIdentity(I);
1533
1534 mGLState.loadPathRenderingMatrix(matrixMode, I);
1535}
1536
1537void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1538{
1539 const auto *pathObj = mResourceManager->getPath(path);
1540 if (!pathObj)
1541 return;
1542
1543 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1544 syncRendererState();
1545
1546 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1547}
1548
1549void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1550{
1551 const auto *pathObj = mResourceManager->getPath(path);
1552 if (!pathObj)
1553 return;
1554
1555 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1556 syncRendererState();
1557
1558 mImplementation->stencilStrokePath(pathObj, reference, mask);
1559}
1560
1561void Context::coverFillPath(GLuint path, GLenum coverMode)
1562{
1563 const auto *pathObj = mResourceManager->getPath(path);
1564 if (!pathObj)
1565 return;
1566
1567 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1568 syncRendererState();
1569
1570 mImplementation->coverFillPath(pathObj, coverMode);
1571}
1572
1573void Context::coverStrokePath(GLuint path, GLenum coverMode)
1574{
1575 const auto *pathObj = mResourceManager->getPath(path);
1576 if (!pathObj)
1577 return;
1578
1579 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1580 syncRendererState();
1581
1582 mImplementation->coverStrokePath(pathObj, coverMode);
1583}
1584
1585void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1586{
1587 const auto *pathObj = mResourceManager->getPath(path);
1588 if (!pathObj)
1589 return;
1590
1591 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1592 syncRendererState();
1593
1594 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1595}
1596
1597void Context::stencilThenCoverStrokePath(GLuint path,
1598 GLint reference,
1599 GLuint mask,
1600 GLenum coverMode)
1601{
1602 const auto *pathObj = mResourceManager->getPath(path);
1603 if (!pathObj)
1604 return;
1605
1606 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1607 syncRendererState();
1608
1609 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1610}
1611
Sami Väisänend59ca052016-06-21 16:10:00 +03001612void Context::coverFillPathInstanced(GLsizei numPaths,
1613 GLenum pathNameType,
1614 const void *paths,
1615 GLuint pathBase,
1616 GLenum coverMode,
1617 GLenum transformType,
1618 const GLfloat *transformValues)
1619{
1620 const auto &pathObjects =
1621 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1622
1623 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1624 syncRendererState();
1625
1626 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1627}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001628
Sami Väisänend59ca052016-06-21 16:10:00 +03001629void Context::coverStrokePathInstanced(GLsizei numPaths,
1630 GLenum pathNameType,
1631 const void *paths,
1632 GLuint pathBase,
1633 GLenum coverMode,
1634 GLenum transformType,
1635 const GLfloat *transformValues)
1636{
1637 const auto &pathObjects =
1638 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1639
1640 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1641 syncRendererState();
1642
1643 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1644 transformValues);
1645}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001646
Sami Väisänend59ca052016-06-21 16:10:00 +03001647void Context::stencilFillPathInstanced(GLsizei numPaths,
1648 GLenum pathNameType,
1649 const void *paths,
1650 GLuint pathBase,
1651 GLenum fillMode,
1652 GLuint mask,
1653 GLenum transformType,
1654 const GLfloat *transformValues)
1655{
1656 const auto &pathObjects =
1657 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1658
1659 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1660 syncRendererState();
1661
1662 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1663 transformValues);
1664}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001665
Sami Väisänend59ca052016-06-21 16:10:00 +03001666void Context::stencilStrokePathInstanced(GLsizei numPaths,
1667 GLenum pathNameType,
1668 const void *paths,
1669 GLuint pathBase,
1670 GLint reference,
1671 GLuint mask,
1672 GLenum transformType,
1673 const GLfloat *transformValues)
1674{
1675 const auto &pathObjects =
1676 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1677
1678 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1679 syncRendererState();
1680
1681 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1682 transformValues);
1683}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001684
Sami Väisänend59ca052016-06-21 16:10:00 +03001685void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1686 GLenum pathNameType,
1687 const void *paths,
1688 GLuint pathBase,
1689 GLenum fillMode,
1690 GLuint mask,
1691 GLenum coverMode,
1692 GLenum transformType,
1693 const GLfloat *transformValues)
1694{
1695 const auto &pathObjects =
1696 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1697
1698 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1699 syncRendererState();
1700
1701 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1702 transformType, transformValues);
1703}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001704
Sami Väisänend59ca052016-06-21 16:10:00 +03001705void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1706 GLenum pathNameType,
1707 const void *paths,
1708 GLuint pathBase,
1709 GLint reference,
1710 GLuint mask,
1711 GLenum coverMode,
1712 GLenum transformType,
1713 const GLfloat *transformValues)
1714{
1715 const auto &pathObjects =
1716 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1717
1718 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1719 syncRendererState();
1720
1721 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1722 transformType, transformValues);
1723}
1724
Sami Väisänen46eaa942016-06-29 10:26:37 +03001725void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1726{
1727 auto *programObject = getProgram(program);
1728
1729 programObject->bindFragmentInputLocation(location, name);
1730}
1731
1732void Context::programPathFragmentInputGen(GLuint program,
1733 GLint location,
1734 GLenum genMode,
1735 GLint components,
1736 const GLfloat *coeffs)
1737{
1738 auto *programObject = getProgram(program);
1739
1740 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1741}
1742
Jamie Madill437fa652016-05-03 15:13:24 -04001743void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001744{
Geoff Langda5777c2014-07-11 09:52:58 -04001745 if (error.isError())
1746 {
1747 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001748
1749 if (!error.getMessage().empty())
1750 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001751 auto *debug = &mGLState.getDebug();
1752 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1753 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001754 }
Geoff Langda5777c2014-07-11 09:52:58 -04001755 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001756}
1757
1758// Get one of the recorded errors and clear its flag, if any.
1759// [OpenGL ES 2.0.24] section 2.5 page 13.
1760GLenum Context::getError()
1761{
Geoff Langda5777c2014-07-11 09:52:58 -04001762 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001763 {
Geoff Langda5777c2014-07-11 09:52:58 -04001764 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001765 }
Geoff Langda5777c2014-07-11 09:52:58 -04001766 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001767 {
Geoff Langda5777c2014-07-11 09:52:58 -04001768 GLenum error = *mErrors.begin();
1769 mErrors.erase(mErrors.begin());
1770 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001771 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001772}
1773
1774GLenum Context::getResetStatus()
1775{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001776 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001777 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001778 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001779 // mResetStatus will be set by the markContextLost callback
1780 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001781 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001782 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001783 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001784 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001785 }
1786
1787 GLenum status = mResetStatus;
1788
1789 if (mResetStatus != GL_NO_ERROR)
1790 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001791 ASSERT(mContextLost);
1792
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001793 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001794 {
1795 mResetStatus = GL_NO_ERROR;
1796 }
1797 }
Jamie Madill893ab082014-05-16 16:56:10 -04001798
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001799 return status;
1800}
1801
1802bool Context::isResetNotificationEnabled()
1803{
1804 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1805}
1806
Corentin Walleze3b10e82015-05-20 11:06:25 -04001807const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001808{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001809 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001810}
1811
1812EGLenum Context::getClientType() const
1813{
1814 return mClientType;
1815}
1816
1817EGLenum Context::getRenderBuffer() const
1818{
Corentin Wallez37c39792015-08-20 14:19:46 -04001819 auto framebufferIt = mFramebufferMap.find(0);
1820 if (framebufferIt != mFramebufferMap.end())
1821 {
1822 const Framebuffer *framebuffer = framebufferIt->second;
1823 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1824
1825 ASSERT(backAttachment != nullptr);
1826 return backAttachment->getSurface()->getRenderBuffer();
1827 }
1828 else
1829 {
1830 return EGL_NONE;
1831 }
Régis Fénéon83107972015-02-05 12:57:44 +01001832}
1833
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001834VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001835{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001836 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001837 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1838 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001839 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001840 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1841
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001842 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001843 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001844
1845 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001846}
1847
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001848TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001849{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001850 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001851 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1852 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001853 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001854 transformFeedback =
1855 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001856 transformFeedback->addRef();
1857 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001858 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001859
1860 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001861}
1862
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001863Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1864{
1865 // Can be called from Bind without a prior call to Gen.
1866 auto framebufferIt = mFramebufferMap.find(framebuffer);
1867 bool neverCreated = framebufferIt == mFramebufferMap.end();
1868 if (neverCreated || framebufferIt->second == nullptr)
1869 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001870 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001871 if (neverCreated)
1872 {
1873 mFramebufferHandleAllocator.reserve(framebuffer);
1874 mFramebufferMap[framebuffer] = newFBO;
1875 return newFBO;
1876 }
1877
1878 framebufferIt->second = newFBO;
1879 }
1880
1881 return framebufferIt->second;
1882}
1883
Geoff Lang36167ab2015-12-07 10:27:14 -05001884bool Context::isVertexArrayGenerated(GLuint vertexArray)
1885{
1886 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1887}
1888
1889bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1890{
1891 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1892}
1893
Shannon Woods53a94a82014-06-24 15:20:36 -04001894void Context::detachTexture(GLuint texture)
1895{
1896 // Simple pass-through to State's detachTexture method, as textures do not require
1897 // allocation map management either here or in the resource manager at detach time.
1898 // Zero textures are held by the Context, and we don't attempt to request them from
1899 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001900 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001901}
1902
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001903void Context::detachBuffer(GLuint buffer)
1904{
Yuly Novikov5807a532015-12-03 13:01:22 -05001905 // Simple pass-through to State's detachBuffer method, since
1906 // only buffer attachments to container objects that are bound to the current context
1907 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001908
Yuly Novikov5807a532015-12-03 13:01:22 -05001909 // [OpenGL ES 3.2] section 5.1.2 page 45:
1910 // Attachments to unbound container objects, such as
1911 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1912 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001913 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001914}
1915
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001916void Context::detachFramebuffer(GLuint framebuffer)
1917{
Shannon Woods53a94a82014-06-24 15:20:36 -04001918 // Framebuffer detachment is handled by Context, because 0 is a valid
1919 // Framebuffer object, and a pointer to it must be passed from Context
1920 // to State at binding time.
1921
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001922 // [OpenGL ES 2.0.24] section 4.4 page 107:
1923 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1924 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1925
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001926 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001927 {
1928 bindReadFramebuffer(0);
1929 }
1930
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001931 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001932 {
1933 bindDrawFramebuffer(0);
1934 }
1935}
1936
1937void Context::detachRenderbuffer(GLuint renderbuffer)
1938{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001939 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001940}
1941
Jamie Madill57a89722013-07-02 11:57:03 -04001942void Context::detachVertexArray(GLuint vertexArray)
1943{
Jamie Madill77a72f62015-04-14 11:18:32 -04001944 // Vertex array detachment is handled by Context, because 0 is a valid
1945 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001946 // binding time.
1947
Jamie Madill57a89722013-07-02 11:57:03 -04001948 // [OpenGL ES 3.0.2] section 2.10 page 43:
1949 // If a vertex array object that is currently bound is deleted, the binding
1950 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001951 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001952 {
1953 bindVertexArray(0);
1954 }
1955}
1956
Geoff Langc8058452014-02-03 12:04:11 -05001957void Context::detachTransformFeedback(GLuint transformFeedback)
1958{
Corentin Walleza2257da2016-04-19 16:43:12 -04001959 // Transform feedback detachment is handled by Context, because 0 is a valid
1960 // transform feedback, and a pointer to it must be passed from Context to State at
1961 // binding time.
1962
1963 // The OpenGL specification doesn't mention what should happen when the currently bound
1964 // transform feedback object is deleted. Since it is a container object, we treat it like
1965 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001966 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04001967 {
1968 bindTransformFeedback(0);
1969 }
Geoff Langc8058452014-02-03 12:04:11 -05001970}
1971
Jamie Madilldc356042013-07-19 16:36:57 -04001972void Context::detachSampler(GLuint sampler)
1973{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001974 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001975}
1976
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001977void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1978{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001979 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001980}
1981
Jamie Madille29d1672013-07-19 16:36:57 -04001982void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1983{
Jamie Madill901b3792016-05-26 09:20:40 -04001984 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001985
1986 Sampler *samplerObject = getSampler(sampler);
1987 ASSERT(samplerObject);
1988
Geoff Lang69cce582015-09-17 13:20:36 -04001989 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001990 switch (pname)
1991 {
Geoff Lang69cce582015-09-17 13:20:36 -04001992 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1993 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1994 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1995 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1996 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1997 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1998 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1999 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2000 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2001 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2002 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002003 }
Geoff Lang69cce582015-09-17 13:20:36 -04002004 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002005}
2006
2007void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2008{
Jamie Madill901b3792016-05-26 09:20:40 -04002009 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002010
2011 Sampler *samplerObject = getSampler(sampler);
2012 ASSERT(samplerObject);
2013
Geoff Lang69cce582015-09-17 13:20:36 -04002014 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002015 switch (pname)
2016 {
Geoff Lang69cce582015-09-17 13:20:36 -04002017 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2018 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2019 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2020 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2021 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2022 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2023 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2024 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2025 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2026 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2027 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002028 }
Geoff Lang69cce582015-09-17 13:20:36 -04002029 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002030}
2031
Jamie Madill9675b802013-07-19 16:36:59 -04002032GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2033{
Jamie Madill901b3792016-05-26 09:20:40 -04002034 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002035
2036 Sampler *samplerObject = getSampler(sampler);
2037 ASSERT(samplerObject);
2038
Geoff Lang69cce582015-09-17 13:20:36 -04002039 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002040 switch (pname)
2041 {
Geoff Lang69cce582015-09-17 13:20:36 -04002042 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2043 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2044 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2045 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2046 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2047 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002048 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2049 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002050 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2051 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2052 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002053 }
Geoff Lang69cce582015-09-17 13:20:36 -04002054 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002055}
2056
2057GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2058{
Jamie Madill901b3792016-05-26 09:20:40 -04002059 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002060
2061 Sampler *samplerObject = getSampler(sampler);
2062 ASSERT(samplerObject);
2063
Geoff Lang69cce582015-09-17 13:20:36 -04002064 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002065 switch (pname)
2066 {
Geoff Lang69cce582015-09-17 13:20:36 -04002067 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2068 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2069 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2070 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2071 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2072 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2073 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2074 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2075 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2076 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2077 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002078 }
Geoff Lang69cce582015-09-17 13:20:36 -04002079 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002080}
2081
Olli Etuahof0fee072016-03-30 15:11:58 +03002082void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2083{
2084 gl::Program *programObject = getProgram(program);
2085 ASSERT(programObject != nullptr);
2086
2087 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2088 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2089}
2090
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002091void Context::initRendererString()
2092{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002093 std::ostringstream rendererString;
2094 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002095 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002096 rendererString << ")";
2097
Geoff Langcec35902014-04-16 10:52:36 -04002098 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002099}
2100
Geoff Langc0b9ef42014-07-02 10:02:37 -04002101const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002102{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002103 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002104}
2105
Geoff Langcec35902014-04-16 10:52:36 -04002106void Context::initExtensionStrings()
2107{
Geoff Lang493daf52014-07-03 13:38:44 -04002108 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002109
Geoff Langc0b9ef42014-07-02 10:02:37 -04002110 std::ostringstream combinedStringStream;
2111 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2112 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002113}
2114
Geoff Langc0b9ef42014-07-02 10:02:37 -04002115const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002116{
2117 return mExtensionString;
2118}
2119
Geoff Langc0b9ef42014-07-02 10:02:37 -04002120const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002121{
2122 return mExtensionStrings[idx];
2123}
2124
2125size_t Context::getExtensionStringCount() const
2126{
2127 return mExtensionStrings.size();
2128}
2129
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002130void Context::beginTransformFeedback(GLenum primitiveMode)
2131{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002133 ASSERT(transformFeedback != nullptr);
2134 ASSERT(!transformFeedback->isPaused());
2135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002136 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002137}
2138
2139bool Context::hasActiveTransformFeedback(GLuint program) const
2140{
2141 for (auto pair : mTransformFeedbackMap)
2142 {
2143 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2144 {
2145 return true;
2146 }
2147 }
2148 return false;
2149}
2150
Jamie Madill00ed7a12016-05-19 13:13:38 -04002151void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002152{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002153 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002154
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002155 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002156
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002157 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002158
Martin Radev1be913c2016-07-11 17:59:16 +03002159 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002160 {
2161 // Disable ES3+ extensions
2162 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002163 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002164 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002165 }
2166
Martin Radev1be913c2016-07-11 17:59:16 +03002167 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002168 {
2169 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2170 //mExtensions.sRGB = false;
2171 }
2172
Jamie Madill00ed7a12016-05-19 13:13:38 -04002173 // Some extensions are always available because they are implemented in the GL layer.
2174 mExtensions.bindUniformLocation = true;
2175 mExtensions.vertexArrayObject = true;
2176
2177 // Enable the no error extension if the context was created with the flag.
2178 mExtensions.noError = mSkipValidation;
2179
Geoff Lang70d0f492015-12-10 17:45:46 -05002180 // Explicitly enable GL_KHR_debug
2181 mExtensions.debug = true;
2182 mExtensions.maxDebugMessageLength = 1024;
2183 mExtensions.maxDebugLoggedMessages = 1024;
2184 mExtensions.maxDebugGroupStackDepth = 1024;
2185 mExtensions.maxLabelLength = 1024;
2186
Geoff Lang301d1612014-07-09 10:34:37 -04002187 // Apply implementation limits
2188 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002189 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2190 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2191
2192 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002193
Geoff Lang900013c2014-07-07 11:32:19 -04002194 mCaps.compressedTextureFormats.clear();
2195
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002196 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002197 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2198 {
2199 GLenum format = i->first;
2200 TextureCaps formatCaps = i->second;
2201
Geoff Lang5d601382014-07-22 15:14:06 -04002202 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002203
Geoff Lang0d8b7242015-09-09 14:56:53 -04002204 // Update the format caps based on the client version and extensions.
2205 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2206 // ES3.
2207 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002208 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002209 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002210 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002211 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002212 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002213
2214 // OpenGL ES does not support multisampling with integer formats
2215 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002216 {
Geoff Langd87878e2014-09-19 15:42:59 -04002217 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002218 }
Geoff Langd87878e2014-09-19 15:42:59 -04002219
2220 if (formatCaps.texturable && formatInfo.compressed)
2221 {
2222 mCaps.compressedTextureFormats.push_back(format);
2223 }
2224
2225 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002226 }
2227}
2228
Jamie Madill1b94d432015-08-07 13:23:23 -04002229void Context::syncRendererState()
2230{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002231 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2232 mImplementation->syncState(mGLState, dirtyBits);
2233 mGLState.clearDirtyBits();
2234 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002235}
2236
Jamie Madillad9f24e2016-02-12 09:27:24 -05002237void Context::syncRendererState(const State::DirtyBits &bitMask,
2238 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002239{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002240 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2241 mImplementation->syncState(mGLState, dirtyBits);
2242 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002243
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002244 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002245}
Jamie Madillc29968b2016-01-20 11:17:23 -05002246
2247void Context::blitFramebuffer(GLint srcX0,
2248 GLint srcY0,
2249 GLint srcX1,
2250 GLint srcY1,
2251 GLint dstX0,
2252 GLint dstY0,
2253 GLint dstX1,
2254 GLint dstY1,
2255 GLbitfield mask,
2256 GLenum filter)
2257{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002258 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002259 ASSERT(drawFramebuffer);
2260
2261 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2262 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2263
Jamie Madillad9f24e2016-02-12 09:27:24 -05002264 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002265
Jamie Madill8415b5f2016-04-26 13:41:39 -04002266 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002267}
Jamie Madillc29968b2016-01-20 11:17:23 -05002268
2269void Context::clear(GLbitfield mask)
2270{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002271 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002272 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002273}
2274
2275void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2276{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002277 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002278 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2279 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002280}
2281
2282void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2283{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002284 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002285 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2286 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002287}
2288
2289void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2290{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002291 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002292 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2293 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002294}
2295
2296void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2297{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002298 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002299 ASSERT(framebufferObject);
2300
2301 // If a buffer is not present, the clear has no effect
2302 if (framebufferObject->getDepthbuffer() == nullptr &&
2303 framebufferObject->getStencilbuffer() == nullptr)
2304 {
2305 return;
2306 }
2307
Jamie Madillad9f24e2016-02-12 09:27:24 -05002308 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002309 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2310 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002311}
2312
2313void Context::readPixels(GLint x,
2314 GLint y,
2315 GLsizei width,
2316 GLsizei height,
2317 GLenum format,
2318 GLenum type,
2319 GLvoid *pixels)
2320{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002321 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002322
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002323 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002324 ASSERT(framebufferObject);
2325
2326 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002327 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002328}
2329
2330void Context::copyTexImage2D(GLenum target,
2331 GLint level,
2332 GLenum internalformat,
2333 GLint x,
2334 GLint y,
2335 GLsizei width,
2336 GLsizei height,
2337 GLint border)
2338{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002339 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002340 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002341
Jamie Madillc29968b2016-01-20 11:17:23 -05002342 Rectangle sourceArea(x, y, width, height);
2343
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002344 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002345 Texture *texture =
2346 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002347 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002348}
2349
2350void Context::copyTexSubImage2D(GLenum target,
2351 GLint level,
2352 GLint xoffset,
2353 GLint yoffset,
2354 GLint x,
2355 GLint y,
2356 GLsizei width,
2357 GLsizei height)
2358{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002359 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002360 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002361
Jamie Madillc29968b2016-01-20 11:17:23 -05002362 Offset destOffset(xoffset, yoffset, 0);
2363 Rectangle sourceArea(x, y, width, height);
2364
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002365 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002366 Texture *texture =
2367 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002368 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002369}
2370
2371void Context::copyTexSubImage3D(GLenum target,
2372 GLint level,
2373 GLint xoffset,
2374 GLint yoffset,
2375 GLint zoffset,
2376 GLint x,
2377 GLint y,
2378 GLsizei width,
2379 GLsizei height)
2380{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002381 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002382 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002383
Jamie Madillc29968b2016-01-20 11:17:23 -05002384 Offset destOffset(xoffset, yoffset, zoffset);
2385 Rectangle sourceArea(x, y, width, height);
2386
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002387 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002388 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002389 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002390}
2391
2392void Context::framebufferTexture2D(GLenum target,
2393 GLenum attachment,
2394 GLenum textarget,
2395 GLuint texture,
2396 GLint level)
2397{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002398 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002399 ASSERT(framebuffer);
2400
2401 if (texture != 0)
2402 {
2403 Texture *textureObj = getTexture(texture);
2404
2405 ImageIndex index = ImageIndex::MakeInvalid();
2406
2407 if (textarget == GL_TEXTURE_2D)
2408 {
2409 index = ImageIndex::Make2D(level);
2410 }
2411 else
2412 {
2413 ASSERT(IsCubeMapTextureTarget(textarget));
2414 index = ImageIndex::MakeCube(textarget, level);
2415 }
2416
2417 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2418 }
2419 else
2420 {
2421 framebuffer->resetAttachment(attachment);
2422 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002423
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002424 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002425}
2426
2427void Context::framebufferRenderbuffer(GLenum target,
2428 GLenum attachment,
2429 GLenum renderbuffertarget,
2430 GLuint renderbuffer)
2431{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002432 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 ASSERT(framebuffer);
2434
2435 if (renderbuffer != 0)
2436 {
2437 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2438 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2439 renderbufferObject);
2440 }
2441 else
2442 {
2443 framebuffer->resetAttachment(attachment);
2444 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002445
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002446 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002447}
2448
2449void Context::framebufferTextureLayer(GLenum target,
2450 GLenum attachment,
2451 GLuint texture,
2452 GLint level,
2453 GLint layer)
2454{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002455 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 ASSERT(framebuffer);
2457
2458 if (texture != 0)
2459 {
2460 Texture *textureObject = getTexture(texture);
2461
2462 ImageIndex index = ImageIndex::MakeInvalid();
2463
2464 if (textureObject->getTarget() == GL_TEXTURE_3D)
2465 {
2466 index = ImageIndex::Make3D(level, layer);
2467 }
2468 else
2469 {
2470 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2471 index = ImageIndex::Make2DArray(level, layer);
2472 }
2473
2474 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2475 }
2476 else
2477 {
2478 framebuffer->resetAttachment(attachment);
2479 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002480
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002481 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002482}
2483
2484void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002486 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002487 ASSERT(framebuffer);
2488 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002489 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002490}
2491
2492void Context::readBuffer(GLenum mode)
2493{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002494 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002495 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002496 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002497}
2498
2499void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2500{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002501 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002502 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002503
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002504 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 ASSERT(framebuffer);
2506
2507 // The specification isn't clear what should be done when the framebuffer isn't complete.
2508 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002509 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002510}
2511
2512void Context::invalidateFramebuffer(GLenum target,
2513 GLsizei numAttachments,
2514 const GLenum *attachments)
2515{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002516 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002517 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002518
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002519 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 ASSERT(framebuffer);
2521
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002522 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002523 {
Jamie Madill437fa652016-05-03 15:13:24 -04002524 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002525 }
Jamie Madill437fa652016-05-03 15:13:24 -04002526
2527 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002528}
2529
2530void Context::invalidateSubFramebuffer(GLenum target,
2531 GLsizei numAttachments,
2532 const GLenum *attachments,
2533 GLint x,
2534 GLint y,
2535 GLsizei width,
2536 GLsizei height)
2537{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002538 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002539 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002540
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002541 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 ASSERT(framebuffer);
2543
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002544 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002545 {
Jamie Madill437fa652016-05-03 15:13:24 -04002546 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002547 }
Jamie Madill437fa652016-05-03 15:13:24 -04002548
2549 Rectangle area(x, y, width, height);
2550 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002551}
2552
Jamie Madill73a84962016-02-12 09:27:23 -05002553void Context::texImage2D(GLenum target,
2554 GLint level,
2555 GLint internalformat,
2556 GLsizei width,
2557 GLsizei height,
2558 GLint border,
2559 GLenum format,
2560 GLenum type,
2561 const GLvoid *pixels)
2562{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002563 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002564
2565 Extents size(width, height, 1);
2566 Texture *texture =
2567 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002568 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002569 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002570}
2571
2572void Context::texImage3D(GLenum target,
2573 GLint level,
2574 GLint internalformat,
2575 GLsizei width,
2576 GLsizei height,
2577 GLsizei depth,
2578 GLint border,
2579 GLenum format,
2580 GLenum type,
2581 const GLvoid *pixels)
2582{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002583 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002584
2585 Extents size(width, height, depth);
2586 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002587 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002588 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002589}
2590
2591void Context::texSubImage2D(GLenum target,
2592 GLint level,
2593 GLint xoffset,
2594 GLint yoffset,
2595 GLsizei width,
2596 GLsizei height,
2597 GLenum format,
2598 GLenum type,
2599 const GLvoid *pixels)
2600{
2601 // Zero sized uploads are valid but no-ops
2602 if (width == 0 || height == 0)
2603 {
2604 return;
2605 }
2606
Jamie Madillad9f24e2016-02-12 09:27:24 -05002607 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002608
2609 Box area(xoffset, yoffset, 0, width, height, 1);
2610 Texture *texture =
2611 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002612 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002613 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002614}
2615
2616void Context::texSubImage3D(GLenum target,
2617 GLint level,
2618 GLint xoffset,
2619 GLint yoffset,
2620 GLint zoffset,
2621 GLsizei width,
2622 GLsizei height,
2623 GLsizei depth,
2624 GLenum format,
2625 GLenum type,
2626 const GLvoid *pixels)
2627{
2628 // Zero sized uploads are valid but no-ops
2629 if (width == 0 || height == 0 || depth == 0)
2630 {
2631 return;
2632 }
2633
Jamie Madillad9f24e2016-02-12 09:27:24 -05002634 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002635
2636 Box area(xoffset, yoffset, zoffset, width, height, depth);
2637 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002638 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002639 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002640}
2641
2642void Context::compressedTexImage2D(GLenum target,
2643 GLint level,
2644 GLenum internalformat,
2645 GLsizei width,
2646 GLsizei height,
2647 GLint border,
2648 GLsizei imageSize,
2649 const GLvoid *data)
2650{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002651 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002652
2653 Extents size(width, height, 1);
2654 Texture *texture =
2655 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002656 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2657 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002658 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002659}
2660
2661void Context::compressedTexImage3D(GLenum target,
2662 GLint level,
2663 GLenum internalformat,
2664 GLsizei width,
2665 GLsizei height,
2666 GLsizei depth,
2667 GLint border,
2668 GLsizei imageSize,
2669 const GLvoid *data)
2670{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002671 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002672
2673 Extents size(width, height, depth);
2674 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002675 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2676 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002677 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002678}
2679
2680void Context::compressedTexSubImage2D(GLenum target,
2681 GLint level,
2682 GLint xoffset,
2683 GLint yoffset,
2684 GLsizei width,
2685 GLsizei height,
2686 GLenum format,
2687 GLsizei imageSize,
2688 const GLvoid *data)
2689{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002690 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002691
2692 Box area(xoffset, yoffset, 0, width, height, 1);
2693 Texture *texture =
2694 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002695 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2696 format, imageSize,
2697 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002698}
2699
2700void Context::compressedTexSubImage3D(GLenum target,
2701 GLint level,
2702 GLint xoffset,
2703 GLint yoffset,
2704 GLint zoffset,
2705 GLsizei width,
2706 GLsizei height,
2707 GLsizei depth,
2708 GLenum format,
2709 GLsizei imageSize,
2710 const GLvoid *data)
2711{
2712 // Zero sized uploads are valid but no-ops
2713 if (width == 0 || height == 0)
2714 {
2715 return;
2716 }
2717
Jamie Madillad9f24e2016-02-12 09:27:24 -05002718 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002719
2720 Box area(xoffset, yoffset, zoffset, width, height, depth);
2721 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002722 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2723 format, imageSize,
2724 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002725}
2726
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002727void Context::generateMipmap(GLenum target)
2728{
2729 Texture *texture = getTargetTexture(target);
2730 handleError(texture->generateMipmap());
2731}
2732
Geoff Lang97073d12016-04-20 10:42:34 -07002733void Context::copyTextureCHROMIUM(GLuint sourceId,
2734 GLuint destId,
2735 GLint internalFormat,
2736 GLenum destType,
2737 GLboolean unpackFlipY,
2738 GLboolean unpackPremultiplyAlpha,
2739 GLboolean unpackUnmultiplyAlpha)
2740{
2741 syncStateForTexImage();
2742
2743 gl::Texture *sourceTexture = getTexture(sourceId);
2744 gl::Texture *destTexture = getTexture(destId);
2745 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2746 unpackPremultiplyAlpha == GL_TRUE,
2747 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2748}
2749
2750void Context::copySubTextureCHROMIUM(GLuint sourceId,
2751 GLuint destId,
2752 GLint xoffset,
2753 GLint yoffset,
2754 GLint x,
2755 GLint y,
2756 GLsizei width,
2757 GLsizei height,
2758 GLboolean unpackFlipY,
2759 GLboolean unpackPremultiplyAlpha,
2760 GLboolean unpackUnmultiplyAlpha)
2761{
2762 // Zero sized copies are valid but no-ops
2763 if (width == 0 || height == 0)
2764 {
2765 return;
2766 }
2767
2768 syncStateForTexImage();
2769
2770 gl::Texture *sourceTexture = getTexture(sourceId);
2771 gl::Texture *destTexture = getTexture(destId);
2772 Offset offset(xoffset, yoffset, 0);
2773 Rectangle area(x, y, width, height);
2774 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
2775 unpackPremultiplyAlpha == GL_TRUE,
2776 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2777}
2778
Olli Etuaho4f667482016-03-30 15:56:35 +03002779void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2780{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002781 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002782 ASSERT(buffer);
2783
2784 if (!buffer->isMapped())
2785 {
2786 *params = nullptr;
2787 }
2788 else
2789 {
2790 *params = buffer->getMapPointer();
2791 }
2792}
2793
2794GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2795{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002797 ASSERT(buffer);
2798
2799 Error error = buffer->map(access);
2800 if (error.isError())
2801 {
Jamie Madill437fa652016-05-03 15:13:24 -04002802 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002803 return nullptr;
2804 }
2805
2806 return buffer->getMapPointer();
2807}
2808
2809GLboolean Context::unmapBuffer(GLenum target)
2810{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002812 ASSERT(buffer);
2813
2814 GLboolean result;
2815 Error error = buffer->unmap(&result);
2816 if (error.isError())
2817 {
Jamie Madill437fa652016-05-03 15:13:24 -04002818 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002819 return GL_FALSE;
2820 }
2821
2822 return result;
2823}
2824
2825GLvoid *Context::mapBufferRange(GLenum target,
2826 GLintptr offset,
2827 GLsizeiptr length,
2828 GLbitfield access)
2829{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002830 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002831 ASSERT(buffer);
2832
2833 Error error = buffer->mapRange(offset, length, access);
2834 if (error.isError())
2835 {
Jamie Madill437fa652016-05-03 15:13:24 -04002836 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002837 return nullptr;
2838 }
2839
2840 return buffer->getMapPointer();
2841}
2842
2843void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2844{
2845 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2846}
2847
Jamie Madillad9f24e2016-02-12 09:27:24 -05002848void Context::syncStateForReadPixels()
2849{
2850 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2851}
2852
2853void Context::syncStateForTexImage()
2854{
2855 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2856}
2857
2858void Context::syncStateForClear()
2859{
2860 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2861}
2862
2863void Context::syncStateForBlit()
2864{
2865 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2866}
2867
Jamie Madillc20ab272016-06-09 07:20:46 -07002868void Context::activeTexture(GLenum texture)
2869{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002870 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002871}
2872
2873void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2874{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002875 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07002876}
2877
2878void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2879{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002880 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002881}
2882
2883void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2884{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002885 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002886}
2887
2888void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2889{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002890 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002891}
2892
2893void Context::clearDepthf(GLclampf depth)
2894{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002895 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07002896}
2897
2898void Context::clearStencil(GLint s)
2899{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002900 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07002901}
2902
2903void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2904{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002905 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002906}
2907
2908void Context::cullFace(GLenum mode)
2909{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002910 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002911}
2912
2913void Context::depthFunc(GLenum func)
2914{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07002916}
2917
2918void Context::depthMask(GLboolean flag)
2919{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002920 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002921}
2922
2923void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2924{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002925 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07002926}
2927
2928void Context::disable(GLenum cap)
2929{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002930 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002931}
2932
2933void Context::disableVertexAttribArray(GLuint index)
2934{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002935 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002936}
2937
2938void Context::enable(GLenum cap)
2939{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002940 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002941}
2942
2943void Context::enableVertexAttribArray(GLuint index)
2944{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002945 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002946}
2947
2948void Context::frontFace(GLenum mode)
2949{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002950 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002951}
2952
2953void Context::hint(GLenum target, GLenum mode)
2954{
2955 switch (target)
2956 {
2957 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002958 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002959 break;
2960
2961 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002962 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002963 break;
2964
2965 default:
2966 UNREACHABLE();
2967 return;
2968 }
2969}
2970
2971void Context::lineWidth(GLfloat width)
2972{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002973 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07002974}
2975
2976void Context::pixelStorei(GLenum pname, GLint param)
2977{
2978 switch (pname)
2979 {
2980 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002982 break;
2983
2984 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002985 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002986 break;
2987
2988 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002989 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002990 break;
2991
2992 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03002993 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002994 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002995 break;
2996
2997 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03002998 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003000 break;
3001
3002 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003003 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003004 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003005 break;
3006
3007 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003008 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003009 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003010 break;
3011
3012 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003013 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003014 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003015 break;
3016
3017 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003018 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003019 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003020 break;
3021
3022 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003023 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003024 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003025 break;
3026
3027 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003028 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003029 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003030 break;
3031
3032 default:
3033 UNREACHABLE();
3034 return;
3035 }
3036}
3037
3038void Context::polygonOffset(GLfloat factor, GLfloat units)
3039{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003041}
3042
3043void Context::sampleCoverage(GLclampf value, GLboolean invert)
3044{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003045 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003046}
3047
3048void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3049{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003050 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003051}
3052
3053void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3054{
3055 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3056 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003057 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003058 }
3059
3060 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3061 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003062 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003063 }
3064}
3065
3066void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3067{
3068 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3069 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003070 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003071 }
3072
3073 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3074 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003075 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003076 }
3077}
3078
3079void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3080{
3081 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3082 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003083 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003084 }
3085
3086 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3087 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003088 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003089 }
3090}
3091
3092void Context::vertexAttrib1f(GLuint index, GLfloat x)
3093{
3094 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003095 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003096}
3097
3098void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3099{
3100 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003101 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003102}
3103
3104void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3105{
3106 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003107 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003108}
3109
3110void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3111{
3112 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003113 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003114}
3115
3116void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3117{
3118 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003119 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003120}
3121
3122void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3123{
3124 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003125 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003126}
3127
3128void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3129{
3130 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003131 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003132}
3133
3134void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3135{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003136 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003137}
3138
3139void Context::vertexAttribPointer(GLuint index,
3140 GLint size,
3141 GLenum type,
3142 GLboolean normalized,
3143 GLsizei stride,
3144 const GLvoid *ptr)
3145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003146 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3147 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003148}
3149
3150void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3151{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003153}
3154
3155void Context::vertexAttribIPointer(GLuint index,
3156 GLint size,
3157 GLenum type,
3158 GLsizei stride,
3159 const GLvoid *pointer)
3160{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003161 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3162 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003163}
3164
3165void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3166{
3167 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003168 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003169}
3170
3171void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3172{
3173 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003174 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003175}
3176
3177void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3178{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003180}
3181
3182void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3183{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003184 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003185}
3186
3187void Context::debugMessageControl(GLenum source,
3188 GLenum type,
3189 GLenum severity,
3190 GLsizei count,
3191 const GLuint *ids,
3192 GLboolean enabled)
3193{
3194 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003195 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3196 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003197}
3198
3199void Context::debugMessageInsert(GLenum source,
3200 GLenum type,
3201 GLuint id,
3202 GLenum severity,
3203 GLsizei length,
3204 const GLchar *buf)
3205{
3206 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003207 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003208}
3209
3210void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3211{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213}
3214
3215GLuint Context::getDebugMessageLog(GLuint count,
3216 GLsizei bufSize,
3217 GLenum *sources,
3218 GLenum *types,
3219 GLuint *ids,
3220 GLenum *severities,
3221 GLsizei *lengths,
3222 GLchar *messageLog)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3225 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003226}
3227
3228void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3229{
3230 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003231 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003232}
3233
3234void Context::popDebugGroup()
3235{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003236 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003237}
3238
Jamie Madillc29968b2016-01-20 11:17:23 -05003239} // namespace gl