blob: 6eb518845560f912ced04c0141b2276e435b9111 [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.
140EGLint GetClientVersion(const egl::AttributeMap &attribs)
141{
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
145GLenum GetResetStrategy(const egl::AttributeMap &attribs)
146{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400147 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
148 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149 switch (attrib)
150 {
151 case EGL_NO_RESET_NOTIFICATION:
152 return GL_NO_RESET_NOTIFICATION_EXT;
153 case EGL_LOSE_CONTEXT_ON_RESET:
154 return GL_LOSE_CONTEXT_ON_RESET_EXT;
155 default:
156 UNREACHABLE();
157 return GL_NONE;
158 }
159}
160
161bool GetRobustAccess(const egl::AttributeMap &attribs)
162{
163 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
164}
165
166bool GetDebug(const egl::AttributeMap &attribs)
167{
168 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
169}
170
171bool GetNoError(const egl::AttributeMap &attribs)
172{
173 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
174}
175
Martin Radev9d901792016-07-15 15:58:58 +0300176std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
177{
178 std::string labelName;
179 if (label != nullptr)
180 {
181 size_t labelLength = length < 0 ? strlen(label) : length;
182 labelName = std::string(label, labelLength);
183 }
184 return labelName;
185}
186
187void GetObjectLabelBase(const std::string &objectLabel,
188 GLsizei bufSize,
189 GLsizei *length,
190 GLchar *label)
191{
192 size_t writeLength = objectLabel.length();
193 if (label != nullptr && bufSize > 0)
194 {
195 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
196 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
197 label[writeLength] = '\0';
198 }
199
200 if (length != nullptr)
201 {
202 *length = static_cast<GLsizei>(writeLength);
203 }
204}
205
Geoff Langf6db0982015-08-25 13:04:00 -0400206} // anonymous namespace
207
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000208namespace gl
209{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000210
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400211Context::Context(rx::EGLImplFactory *implFactory,
212 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400213 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500214 const egl::AttributeMap &attribs)
215 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700216 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500217 mCaps,
218 mTextureCaps,
219 mExtensions,
220 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500221 mLimitations,
222 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700223 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500224 mCompiler(nullptr),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500225 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400226 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500227 mClientType(EGL_OPENGL_ES_API),
228 mHasBeenCurrent(false),
229 mContextLost(false),
230 mResetStatus(GL_NO_ERROR),
231 mResetStrategy(GetResetStrategy(attribs)),
232 mRobustAccess(GetRobustAccess(attribs)),
233 mCurrentSurface(nullptr),
234 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000235{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500236 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000237
Jamie Madill00ed7a12016-05-19 13:13:38 -0400238 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400239
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700240 mGLState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100241
Shannon Woods53a94a82014-06-24 15:20:36 -0400242 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400243
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400244 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000245 {
246 mResourceManager = shareContext->mResourceManager;
247 mResourceManager->addRef();
248 }
249 else
250 {
Jamie Madill901b3792016-05-26 09:20:40 -0400251 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000252 }
253
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700254 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400255
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256 // [OpenGL ES 2.0.24] section 3.7 page 83:
257 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
258 // and cube map texture state vectors respectively associated with them.
259 // In order that access to these initial textures not be lost, they are treated as texture
260 // objects all of whose names are 0.
261
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400262 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500263 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500264
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400265 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500266 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400267
268 if (mClientVersion >= 3)
269 {
270 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400271 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500272 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400273
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400274 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500275 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400276 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277
Ian Ewellbda75592016-04-18 17:25:54 -0400278 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
279 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400280 Texture *zeroTextureExternal =
281 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400282 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
283 }
284
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700285 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500286
Jamie Madill57a89722013-07-02 11:57:03 -0400287 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 bindArrayBuffer(0);
289 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400290
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291 bindRenderbuffer(0);
292
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000293 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400294 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000295 {
296 bindIndexedUniformBuffer(0, i, 0, -1);
297 }
298
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000299 bindCopyReadBuffer(0);
300 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000301 bindPixelPackBuffer(0);
302 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000303
Geoff Lang1a683462015-09-29 15:09:59 -0400304 if (mClientVersion >= 3)
305 {
306 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
307 // In the initial state, a default transform feedback object is bound and treated as
308 // a transform feedback object with a name of zero. That object is bound any time
309 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400310 bindTransformFeedback(0);
311 }
Geoff Langc8058452014-02-03 12:04:11 -0500312
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700313 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500314
315 // Initialize dirty bit masks
316 // TODO(jmadill): additional ES3 state
317 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
318 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
319 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
320 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
321 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
322 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400323 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500324 // No dirty objects.
325
326 // Readpixels uses the pack state and read FBO
327 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
328 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
329 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
330 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
331 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400332 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500333 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
334
335 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
336 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
337 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
338 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
339 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
340 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
341 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
342 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
343 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
344 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
345 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
346 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
347
348 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
349 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
350 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
351 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400352
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400353 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000354}
355
356Context::~Context()
357{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700358 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000359
Corentin Wallez37c39792015-08-20 14:19:46 -0400360 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000361 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400362 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400363 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400364 {
365 SafeDelete(framebuffer.second);
366 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000367 }
368
Corentin Wallez80b24112015-08-25 16:41:57 -0400369 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400371 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000372 }
373
Corentin Wallez80b24112015-08-25 16:41:57 -0400374 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000375 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400376 if (query.second != nullptr)
377 {
378 query.second->release();
379 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000380 }
381
Corentin Wallez80b24112015-08-25 16:41:57 -0400382 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400383 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400384 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400385 }
386
Corentin Wallez80b24112015-08-25 16:41:57 -0400387 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500388 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500389 if (transformFeedback.second != nullptr)
390 {
391 transformFeedback.second->release();
392 }
Geoff Langc8058452014-02-03 12:04:11 -0500393 }
394
Jamie Madilldedd7b92014-11-05 16:30:36 -0500395 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400396 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500397 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400398 }
399 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000400
Corentin Wallez51706ea2015-08-07 14:39:22 -0400401 if (mCurrentSurface != nullptr)
402 {
403 releaseSurface();
404 }
405
Jamie Madill1e9ae072014-11-06 15:27:21 -0500406 if (mResourceManager)
407 {
408 mResourceManager->release();
409 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500410
411 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412}
413
daniel@transgaming.comad629872012-11-28 19:32:06 +0000414void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415{
Jamie Madill77a72f62015-04-14 11:18:32 -0400416 ASSERT(surface != nullptr);
417
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418 if (!mHasBeenCurrent)
419 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400421 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700423 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
424 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425
426 mHasBeenCurrent = true;
427 }
428
Jamie Madill1b94d432015-08-07 13:23:23 -0400429 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700430 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400431
Corentin Wallez51706ea2015-08-07 14:39:22 -0400432 if (mCurrentSurface)
433 {
434 releaseSurface();
435 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000436 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400437 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000438
Corentin Wallez37c39792015-08-20 14:19:46 -0400439 // Update default framebuffer, the binding of the previous default
440 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400441 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400442 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700443 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400444 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700445 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400446 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700447 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400448 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700449 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400450 }
451 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400452 }
Ian Ewell292f0052016-02-04 10:37:32 -0500453
454 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700455 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000456}
457
Jamie Madill77a72f62015-04-14 11:18:32 -0400458void Context::releaseSurface()
459{
Corentin Wallez37c39792015-08-20 14:19:46 -0400460 ASSERT(mCurrentSurface != nullptr);
461
462 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400463 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400464 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700465 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400466 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700467 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 }
473 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400474 }
475
Corentin Wallez51706ea2015-08-07 14:39:22 -0400476 mCurrentSurface->setIsCurrent(false);
477 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400478}
479
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000480// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000481void Context::markContextLost()
482{
483 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
484 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
485 mContextLost = true;
486}
487
488bool Context::isContextLost()
489{
490 return mContextLost;
491}
492
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493GLuint Context::createBuffer()
494{
495 return mResourceManager->createBuffer();
496}
497
498GLuint Context::createProgram()
499{
Jamie Madill901b3792016-05-26 09:20:40 -0400500 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000501}
502
503GLuint Context::createShader(GLenum type)
504{
Jamie Madill901b3792016-05-26 09:20:40 -0400505 return mResourceManager->createShader(mImplementation.get(),
506 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507}
508
509GLuint Context::createTexture()
510{
511 return mResourceManager->createTexture();
512}
513
514GLuint Context::createRenderbuffer()
515{
516 return mResourceManager->createRenderbuffer();
517}
518
Geoff Lang882033e2014-09-30 11:26:07 -0400519GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400520{
Jamie Madill901b3792016-05-26 09:20:40 -0400521 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400522
Cooper Partind8e62a32015-01-29 15:21:25 -0800523 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400524}
525
Sami Väisänene45e53b2016-05-25 10:36:04 +0300526GLuint Context::createPaths(GLsizei range)
527{
528 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
529 if (resultOrError.isError())
530 {
531 handleError(resultOrError.getError());
532 return 0;
533 }
534 return resultOrError.getResult();
535}
536
Jamie Madill57a89722013-07-02 11:57:03 -0400537GLuint Context::createVertexArray()
538{
Geoff Lang36167ab2015-12-07 10:27:14 -0500539 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
540 mVertexArrayMap[vertexArray] = nullptr;
541 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400542}
543
Jamie Madilldc356042013-07-19 16:36:57 -0400544GLuint Context::createSampler()
545{
546 return mResourceManager->createSampler();
547}
548
Geoff Langc8058452014-02-03 12:04:11 -0500549GLuint Context::createTransformFeedback()
550{
Geoff Lang36167ab2015-12-07 10:27:14 -0500551 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
552 mTransformFeedbackMap[transformFeedback] = nullptr;
553 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500554}
555
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000556// Returns an unused framebuffer name
557GLuint Context::createFramebuffer()
558{
559 GLuint handle = mFramebufferHandleAllocator.allocate();
560
561 mFramebufferMap[handle] = NULL;
562
563 return handle;
564}
565
Jamie Madill33dc8432013-07-26 11:55:05 -0400566GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567{
Jamie Madill33dc8432013-07-26 11:55:05 -0400568 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000569
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400570 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571
572 return handle;
573}
574
575// Returns an unused query name
576GLuint Context::createQuery()
577{
578 GLuint handle = mQueryHandleAllocator.allocate();
579
580 mQueryMap[handle] = NULL;
581
582 return handle;
583}
584
585void Context::deleteBuffer(GLuint buffer)
586{
587 if (mResourceManager->getBuffer(buffer))
588 {
589 detachBuffer(buffer);
590 }
Jamie Madill893ab082014-05-16 16:56:10 -0400591
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592 mResourceManager->deleteBuffer(buffer);
593}
594
595void Context::deleteShader(GLuint shader)
596{
597 mResourceManager->deleteShader(shader);
598}
599
600void Context::deleteProgram(GLuint program)
601{
602 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603}
604
605void Context::deleteTexture(GLuint texture)
606{
607 if (mResourceManager->getTexture(texture))
608 {
609 detachTexture(texture);
610 }
611
612 mResourceManager->deleteTexture(texture);
613}
614
615void Context::deleteRenderbuffer(GLuint renderbuffer)
616{
617 if (mResourceManager->getRenderbuffer(renderbuffer))
618 {
619 detachRenderbuffer(renderbuffer);
620 }
Jamie Madill893ab082014-05-16 16:56:10 -0400621
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622 mResourceManager->deleteRenderbuffer(renderbuffer);
623}
624
Jamie Madillcd055f82013-07-26 11:55:15 -0400625void Context::deleteFenceSync(GLsync fenceSync)
626{
627 // The spec specifies the underlying Fence object is not deleted until all current
628 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
629 // and since our API is currently designed for being called from a single thread, we can delete
630 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700631 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400632}
633
Sami Väisänene45e53b2016-05-25 10:36:04 +0300634void Context::deletePaths(GLuint first, GLsizei range)
635{
636 mResourceManager->deletePaths(first, range);
637}
638
639bool Context::hasPathData(GLuint path) const
640{
641 const auto *pathObj = mResourceManager->getPath(path);
642 if (pathObj == nullptr)
643 return false;
644
645 return pathObj->hasPathData();
646}
647
648bool Context::hasPath(GLuint path) const
649{
650 return mResourceManager->hasPath(path);
651}
652
653void Context::setPathCommands(GLuint path,
654 GLsizei numCommands,
655 const GLubyte *commands,
656 GLsizei numCoords,
657 GLenum coordType,
658 const void *coords)
659{
660 auto *pathObject = mResourceManager->getPath(path);
661
662 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
663}
664
665void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
666{
667 auto *pathObj = mResourceManager->getPath(path);
668
669 switch (pname)
670 {
671 case GL_PATH_STROKE_WIDTH_CHROMIUM:
672 pathObj->setStrokeWidth(value);
673 break;
674 case GL_PATH_END_CAPS_CHROMIUM:
675 pathObj->setEndCaps(static_cast<GLenum>(value));
676 break;
677 case GL_PATH_JOIN_STYLE_CHROMIUM:
678 pathObj->setJoinStyle(static_cast<GLenum>(value));
679 break;
680 case GL_PATH_MITER_LIMIT_CHROMIUM:
681 pathObj->setMiterLimit(value);
682 break;
683 case GL_PATH_STROKE_BOUND_CHROMIUM:
684 pathObj->setStrokeBound(value);
685 break;
686 default:
687 UNREACHABLE();
688 break;
689 }
690}
691
692void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
693{
694 const auto *pathObj = mResourceManager->getPath(path);
695
696 switch (pname)
697 {
698 case GL_PATH_STROKE_WIDTH_CHROMIUM:
699 *value = pathObj->getStrokeWidth();
700 break;
701 case GL_PATH_END_CAPS_CHROMIUM:
702 *value = static_cast<GLfloat>(pathObj->getEndCaps());
703 break;
704 case GL_PATH_JOIN_STYLE_CHROMIUM:
705 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
706 break;
707 case GL_PATH_MITER_LIMIT_CHROMIUM:
708 *value = pathObj->getMiterLimit();
709 break;
710 case GL_PATH_STROKE_BOUND_CHROMIUM:
711 *value = pathObj->getStrokeBound();
712 break;
713 default:
714 UNREACHABLE();
715 break;
716 }
717}
718
719void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
720{
721 mGLState.setPathStencilFunc(func, ref, mask);
722}
723
Jamie Madill57a89722013-07-02 11:57:03 -0400724void Context::deleteVertexArray(GLuint vertexArray)
725{
Geoff Lang36167ab2015-12-07 10:27:14 -0500726 auto iter = mVertexArrayMap.find(vertexArray);
727 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000728 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500729 VertexArray *vertexArrayObject = iter->second;
730 if (vertexArrayObject != nullptr)
731 {
732 detachVertexArray(vertexArray);
733 delete vertexArrayObject;
734 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000735
Geoff Lang36167ab2015-12-07 10:27:14 -0500736 mVertexArrayMap.erase(iter);
737 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400738 }
739}
740
Jamie Madilldc356042013-07-19 16:36:57 -0400741void Context::deleteSampler(GLuint sampler)
742{
743 if (mResourceManager->getSampler(sampler))
744 {
745 detachSampler(sampler);
746 }
747
748 mResourceManager->deleteSampler(sampler);
749}
750
Geoff Langc8058452014-02-03 12:04:11 -0500751void Context::deleteTransformFeedback(GLuint transformFeedback)
752{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500753 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500754 if (iter != mTransformFeedbackMap.end())
755 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500756 TransformFeedback *transformFeedbackObject = iter->second;
757 if (transformFeedbackObject != nullptr)
758 {
759 detachTransformFeedback(transformFeedback);
760 transformFeedbackObject->release();
761 }
762
Geoff Lang50b3fe82015-12-08 14:49:12 +0000763 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500764 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500765 }
766}
767
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000768void Context::deleteFramebuffer(GLuint framebuffer)
769{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500770 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000771
772 if (framebufferObject != mFramebufferMap.end())
773 {
774 detachFramebuffer(framebuffer);
775
776 mFramebufferHandleAllocator.release(framebufferObject->first);
777 delete framebufferObject->second;
778 mFramebufferMap.erase(framebufferObject);
779 }
780}
781
Jamie Madill33dc8432013-07-26 11:55:05 -0400782void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500784 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000785
Jamie Madill33dc8432013-07-26 11:55:05 -0400786 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400788 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400790 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000791 }
792}
793
794void Context::deleteQuery(GLuint query)
795{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500796 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000797 if (queryObject != mQueryMap.end())
798 {
799 mQueryHandleAllocator.release(queryObject->first);
800 if (queryObject->second)
801 {
802 queryObject->second->release();
803 }
804 mQueryMap.erase(queryObject);
805 }
806}
807
Geoff Lang70d0f492015-12-10 17:45:46 -0500808Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809{
810 return mResourceManager->getBuffer(handle);
811}
812
Geoff Lang48dcae72014-02-05 16:28:24 -0500813Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000814{
815 return mResourceManager->getShader(handle);
816}
817
Geoff Lang48dcae72014-02-05 16:28:24 -0500818Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819{
820 return mResourceManager->getProgram(handle);
821}
822
Jamie Madill570f7c82014-07-03 10:38:54 -0400823Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824{
825 return mResourceManager->getTexture(handle);
826}
827
Geoff Lang70d0f492015-12-10 17:45:46 -0500828Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829{
830 return mResourceManager->getRenderbuffer(handle);
831}
832
Jamie Madillcd055f82013-07-26 11:55:15 -0400833FenceSync *Context::getFenceSync(GLsync handle) const
834{
Minmin Gong794e0002015-04-07 18:31:54 -0700835 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400836}
837
Jamie Madill57a89722013-07-02 11:57:03 -0400838VertexArray *Context::getVertexArray(GLuint handle) const
839{
840 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500841 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400842}
843
Jamie Madilldc356042013-07-19 16:36:57 -0400844Sampler *Context::getSampler(GLuint handle) const
845{
846 return mResourceManager->getSampler(handle);
847}
848
Geoff Langc8058452014-02-03 12:04:11 -0500849TransformFeedback *Context::getTransformFeedback(GLuint handle) const
850{
Geoff Lang36167ab2015-12-07 10:27:14 -0500851 auto iter = mTransformFeedbackMap.find(handle);
852 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500853}
854
Geoff Lang70d0f492015-12-10 17:45:46 -0500855LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
856{
857 switch (identifier)
858 {
859 case GL_BUFFER:
860 return getBuffer(name);
861 case GL_SHADER:
862 return getShader(name);
863 case GL_PROGRAM:
864 return getProgram(name);
865 case GL_VERTEX_ARRAY:
866 return getVertexArray(name);
867 case GL_QUERY:
868 return getQuery(name);
869 case GL_TRANSFORM_FEEDBACK:
870 return getTransformFeedback(name);
871 case GL_SAMPLER:
872 return getSampler(name);
873 case GL_TEXTURE:
874 return getTexture(name);
875 case GL_RENDERBUFFER:
876 return getRenderbuffer(name);
877 case GL_FRAMEBUFFER:
878 return getFramebuffer(name);
879 default:
880 UNREACHABLE();
881 return nullptr;
882 }
883}
884
885LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
886{
887 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
888}
889
Martin Radev9d901792016-07-15 15:58:58 +0300890void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
891{
892 LabeledObject *object = getLabeledObject(identifier, name);
893 ASSERT(object != nullptr);
894
895 std::string labelName = GetObjectLabelFromPointer(length, label);
896 object->setLabel(labelName);
897}
898
899void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
900{
901 LabeledObject *object = getLabeledObjectFromPtr(ptr);
902 ASSERT(object != nullptr);
903
904 std::string labelName = GetObjectLabelFromPointer(length, label);
905 object->setLabel(labelName);
906}
907
908void Context::getObjectLabel(GLenum identifier,
909 GLuint name,
910 GLsizei bufSize,
911 GLsizei *length,
912 GLchar *label) const
913{
914 LabeledObject *object = getLabeledObject(identifier, name);
915 ASSERT(object != nullptr);
916
917 const std::string &objectLabel = object->getLabel();
918 GetObjectLabelBase(objectLabel, bufSize, length, label);
919}
920
921void Context::getObjectPtrLabel(const void *ptr,
922 GLsizei bufSize,
923 GLsizei *length,
924 GLchar *label) const
925{
926 LabeledObject *object = getLabeledObjectFromPtr(ptr);
927 ASSERT(object != nullptr);
928
929 const std::string &objectLabel = object->getLabel();
930 GetObjectLabelBase(objectLabel, bufSize, length, label);
931}
932
Jamie Madilldc356042013-07-19 16:36:57 -0400933bool Context::isSampler(GLuint samplerName) const
934{
935 return mResourceManager->isSampler(samplerName);
936}
937
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500938void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000939{
Jamie Madill901b3792016-05-26 09:20:40 -0400940 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700941 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942}
943
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500944void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945{
Jamie Madill901b3792016-05-26 09:20:40 -0400946 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700947 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948}
949
Jamie Madilldedd7b92014-11-05 16:30:36 -0500950void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500952 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953
Jamie Madilldedd7b92014-11-05 16:30:36 -0500954 if (handle == 0)
955 {
956 texture = mZeroTextures[target].get();
957 }
958 else
959 {
Jamie Madill901b3792016-05-26 09:20:40 -0400960 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500961 }
962
963 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700964 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000965}
966
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500967void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500969 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700970 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971}
972
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500973void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500975 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700976 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977}
978
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500979void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980{
Jamie Madill901b3792016-05-26 09:20:40 -0400981 Renderbuffer *renderbuffer =
982 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400987{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700989 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400990}
991
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500992void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400993{
Geoff Lang76b10c92014-09-05 16:28:14 -0400994 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400995 Sampler *sampler =
996 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700997 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400998}
999
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001000void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001001{
Jamie Madill901b3792016-05-26 09:20:40 -04001002 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001003 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001004}
1005
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001006void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1007 GLuint index,
1008 GLintptr offset,
1009 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001010{
Jamie Madill901b3792016-05-26 09:20:40 -04001011 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001012 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001013}
1014
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001015void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001016{
Jamie Madill901b3792016-05-26 09:20:40 -04001017 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001018 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019}
1020
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001021void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1022 GLuint index,
1023 GLintptr offset,
1024 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001025{
Jamie Madill901b3792016-05-26 09:20:40 -04001026 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001031{
Jamie Madill901b3792016-05-26 09:20:40 -04001032 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037{
Jamie Madill901b3792016-05-26 09:20:40 -04001038 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001039 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040}
1041
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001042void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001043{
Jamie Madill901b3792016-05-26 09:20:40 -04001044 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001045 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001046}
1047
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001048void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049{
Jamie Madill901b3792016-05-26 09:20:40 -04001050 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001051 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052}
1053
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001054void Context::useProgram(GLuint program)
1055{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001056 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001057}
1058
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001059void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001060{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001061 TransformFeedback *transformFeedback =
1062 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001064}
1065
Geoff Lang5aad9672014-09-08 11:10:42 -04001066Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001067{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001069 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070
Geoff Lang5aad9672014-09-08 11:10:42 -04001071 // begin query
1072 Error error = queryObject->begin();
1073 if (error.isError())
1074 {
1075 return error;
1076 }
1077
1078 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001079 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080
Geoff Lang5aad9672014-09-08 11:10:42 -04001081 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082}
1083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001086 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001087 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088
Geoff Lang5aad9672014-09-08 11:10:42 -04001089 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001090
Geoff Lang5aad9672014-09-08 11:10:42 -04001091 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001092 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001093
1094 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001095}
1096
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001097Error Context::queryCounter(GLuint id, GLenum target)
1098{
1099 ASSERT(target == GL_TIMESTAMP_EXT);
1100
1101 Query *queryObject = getQuery(id, true, target);
1102 ASSERT(queryObject);
1103
1104 return queryObject->queryCounter();
1105}
1106
1107void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1108{
1109 switch (pname)
1110 {
1111 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001112 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001113 break;
1114 case GL_QUERY_COUNTER_BITS_EXT:
1115 switch (target)
1116 {
1117 case GL_TIME_ELAPSED_EXT:
1118 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1119 break;
1120 case GL_TIMESTAMP_EXT:
1121 params[0] = getExtensions().queryCounterBitsTimestamp;
1122 break;
1123 default:
1124 UNREACHABLE();
1125 params[0] = 0;
1126 break;
1127 }
1128 break;
1129 default:
1130 UNREACHABLE();
1131 return;
1132 }
1133}
1134
1135Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1136{
1137 return GetQueryObjectParameter(this, id, pname, params);
1138}
1139
1140Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1141{
1142 return GetQueryObjectParameter(this, id, pname, params);
1143}
1144
1145Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1146{
1147 return GetQueryObjectParameter(this, id, pname, params);
1148}
1149
1150Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1151{
1152 return GetQueryObjectParameter(this, id, pname, params);
1153}
1154
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001155Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001157 auto framebufferIt = mFramebufferMap.find(handle);
1158 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159}
1160
Jamie Madill33dc8432013-07-26 11:55:05 -04001161FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001163 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164
Jamie Madill33dc8432013-07-26 11:55:05 -04001165 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001166 {
1167 return NULL;
1168 }
1169 else
1170 {
1171 return fence->second;
1172 }
1173}
1174
1175Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1176{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001177 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178
1179 if (query == mQueryMap.end())
1180 {
1181 return NULL;
1182 }
1183 else
1184 {
1185 if (!query->second && create)
1186 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001187 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188 query->second->addRef();
1189 }
1190 return query->second;
1191 }
1192}
1193
Geoff Lang70d0f492015-12-10 17:45:46 -05001194Query *Context::getQuery(GLuint handle) const
1195{
1196 auto iter = mQueryMap.find(handle);
1197 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1198}
1199
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001200Texture *Context::getTargetTexture(GLenum target) const
1201{
Ian Ewellbda75592016-04-18 17:25:54 -04001202 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001203 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001204}
1205
Geoff Lang76b10c92014-09-05 16:28:14 -04001206Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001207{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001208 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209}
1210
Geoff Lang492a7e42014-11-05 13:27:06 -05001211Compiler *Context::getCompiler() const
1212{
1213 return mCompiler;
1214}
1215
Jamie Madill893ab082014-05-16 16:56:10 -04001216void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217{
1218 switch (pname)
1219 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001220 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001221 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001223 mGLState.getBooleanv(pname, params);
1224 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226}
1227
Jamie Madill893ab082014-05-16 16:56:10 -04001228void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229{
Shannon Woods53a94a82014-06-24 15:20:36 -04001230 // Queries about context capabilities and maximums are answered by Context.
1231 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 switch (pname)
1233 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001234 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001235 params[0] = mCaps.minAliasedLineWidth;
1236 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 break;
1238 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001239 params[0] = mCaps.minAliasedPointSize;
1240 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001241 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001242 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001243 ASSERT(mExtensions.textureFilterAnisotropic);
1244 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001245 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001246 case GL_MAX_TEXTURE_LOD_BIAS:
1247 *params = mCaps.maxLODBias;
1248 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001249
1250 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1251 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1252 {
1253 ASSERT(mExtensions.pathRendering);
1254 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1255 memcpy(params, m, 16 * sizeof(GLfloat));
1256 }
1257 break;
1258
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001260 mGLState.getFloatv(pname, params);
1261 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263}
1264
Jamie Madill893ab082014-05-16 16:56:10 -04001265void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266{
Shannon Woods53a94a82014-06-24 15:20:36 -04001267 // Queries about context capabilities and maximums are answered by Context.
1268 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001269
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 switch (pname)
1271 {
Geoff Lang301d1612014-07-09 10:34:37 -04001272 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1273 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1274 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001275 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1276 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1277 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001278 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1279 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1280 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001281 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001282 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1283 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1284 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001285 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001286 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001287 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1288 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1289 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1290 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001291 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1292 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001293 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1294 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001295 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001296 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1297 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1298 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1299 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001300 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1301 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001302 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1303 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001304 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1305 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1306 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001307 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1308 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1309 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001310 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311 case GL_MAX_VIEWPORT_DIMS:
1312 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001313 params[0] = mCaps.maxViewportWidth;
1314 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315 }
1316 break;
1317 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001318 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1321 *params = mResetStrategy;
1322 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001323 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001324 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001326 case GL_SHADER_BINARY_FORMATS:
1327 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1328 break;
1329 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001330 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001331 break;
1332 case GL_PROGRAM_BINARY_FORMATS:
1333 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001335 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001336 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001337 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001338
1339 // GL_KHR_debug
1340 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1341 *params = mExtensions.maxDebugMessageLength;
1342 break;
1343 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1344 *params = mExtensions.maxDebugLoggedMessages;
1345 break;
1346 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1347 *params = mExtensions.maxDebugGroupStackDepth;
1348 break;
1349 case GL_MAX_LABEL_LENGTH:
1350 *params = mExtensions.maxLabelLength;
1351 break;
1352
Ian Ewell53f59f42016-01-28 17:36:55 -05001353 // GL_EXT_disjoint_timer_query
1354 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001355 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001356 break;
1357
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001358 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001359 mGLState.getIntegerv(mState, pname, params);
1360 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001361 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001362}
1363
Jamie Madill893ab082014-05-16 16:56:10 -04001364void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001365{
Shannon Woods53a94a82014-06-24 15:20:36 -04001366 // Queries about context capabilities and maximums are answered by Context.
1367 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001368 switch (pname)
1369 {
1370 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001371 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001372 break;
1373 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001374 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001375 break;
1376 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001377 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001378 break;
1379 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001380 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001381 break;
1382 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001383 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001384 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001385
1386 // GL_EXT_disjoint_timer_query
1387 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001388 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001389 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001390 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001391 UNREACHABLE();
1392 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001393 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001394}
1395
Geoff Lang70d0f492015-12-10 17:45:46 -05001396void Context::getPointerv(GLenum pname, void **params) const
1397{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001398 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001399}
1400
Shannon Woods1b2fb852013-08-19 14:28:48 -04001401bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1402{
Shannon Woods53a94a82014-06-24 15:20:36 -04001403 // Queries about context capabilities and maximums are answered by Context.
1404 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001405 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001406 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001407 return mGLState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001408}
1409
1410bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1411{
Shannon Woods53a94a82014-06-24 15:20:36 -04001412 // Queries about context capabilities and maximums are answered by Context.
1413 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001414 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001416 return mGLState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001417}
1418
Geoff Langf6db0982015-08-25 13:04:00 -04001419Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001420{
Jamie Madill1b94d432015-08-07 13:23:23 -04001421 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001422 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001423 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001424
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001425 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001426}
1427
Geoff Langf6db0982015-08-25 13:04:00 -04001428Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1429{
1430 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001431 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001432 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001433
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001434 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001435}
1436
1437Error Context::drawElements(GLenum mode,
1438 GLsizei count,
1439 GLenum type,
1440 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001441 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001442{
Jamie Madill1b94d432015-08-07 13:23:23 -04001443 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001444 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001445}
1446
1447Error Context::drawElementsInstanced(GLenum mode,
1448 GLsizei count,
1449 GLenum type,
1450 const GLvoid *indices,
1451 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001452 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001453{
1454 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001455 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1456 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001457}
1458
1459Error Context::drawRangeElements(GLenum mode,
1460 GLuint start,
1461 GLuint end,
1462 GLsizei count,
1463 GLenum type,
1464 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001465 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001466{
1467 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001468 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001469}
1470
Geoff Lang129753a2015-01-09 16:52:09 -05001471Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001472{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001473 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001474}
1475
1476Error Context::finish()
1477{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001478 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001479}
1480
Austin Kinross6ee1e782015-05-29 17:05:37 -07001481void Context::insertEventMarker(GLsizei length, const char *marker)
1482{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001483 ASSERT(mImplementation);
1484 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001485}
1486
1487void Context::pushGroupMarker(GLsizei length, const char *marker)
1488{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001489 ASSERT(mImplementation);
1490 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001491}
1492
1493void Context::popGroupMarker()
1494{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001495 ASSERT(mImplementation);
1496 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001497}
1498
Geoff Langd8605522016-04-13 10:19:12 -04001499void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1500{
1501 Program *programObject = getProgram(program);
1502 ASSERT(programObject);
1503
1504 programObject->bindUniformLocation(location, name);
1505}
1506
Sami Väisänena797e062016-05-12 15:23:40 +03001507void Context::setCoverageModulation(GLenum components)
1508{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001509 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001510}
1511
Sami Väisänene45e53b2016-05-25 10:36:04 +03001512void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1513{
1514 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1515}
1516
1517void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1518{
1519 GLfloat I[16];
1520 angle::Matrix<GLfloat>::setToIdentity(I);
1521
1522 mGLState.loadPathRenderingMatrix(matrixMode, I);
1523}
1524
1525void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1526{
1527 const auto *pathObj = mResourceManager->getPath(path);
1528 if (!pathObj)
1529 return;
1530
1531 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1532 syncRendererState();
1533
1534 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1535}
1536
1537void Context::stencilStrokePath(GLuint path, GLint reference, 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->stencilStrokePath(pathObj, reference, mask);
1547}
1548
1549void Context::coverFillPath(GLuint path, GLenum coverMode)
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->coverFillPath(pathObj, coverMode);
1559}
1560
1561void Context::coverStrokePath(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->coverStrokePath(pathObj, coverMode);
1571}
1572
1573void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, 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->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1583}
1584
1585void Context::stencilThenCoverStrokePath(GLuint path,
1586 GLint reference,
1587 GLuint mask,
1588 GLenum coverMode)
1589{
1590 const auto *pathObj = mResourceManager->getPath(path);
1591 if (!pathObj)
1592 return;
1593
1594 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1595 syncRendererState();
1596
1597 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1598}
1599
Sami Väisänend59ca052016-06-21 16:10:00 +03001600void Context::coverFillPathInstanced(GLsizei numPaths,
1601 GLenum pathNameType,
1602 const void *paths,
1603 GLuint pathBase,
1604 GLenum coverMode,
1605 GLenum transformType,
1606 const GLfloat *transformValues)
1607{
1608 const auto &pathObjects =
1609 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1610
1611 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1612 syncRendererState();
1613
1614 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1615}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001616
Sami Väisänend59ca052016-06-21 16:10:00 +03001617void Context::coverStrokePathInstanced(GLsizei numPaths,
1618 GLenum pathNameType,
1619 const void *paths,
1620 GLuint pathBase,
1621 GLenum coverMode,
1622 GLenum transformType,
1623 const GLfloat *transformValues)
1624{
1625 const auto &pathObjects =
1626 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1627
1628 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1629 syncRendererState();
1630
1631 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1632 transformValues);
1633}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001634
Sami Väisänend59ca052016-06-21 16:10:00 +03001635void Context::stencilFillPathInstanced(GLsizei numPaths,
1636 GLenum pathNameType,
1637 const void *paths,
1638 GLuint pathBase,
1639 GLenum fillMode,
1640 GLuint mask,
1641 GLenum transformType,
1642 const GLfloat *transformValues)
1643{
1644 const auto &pathObjects =
1645 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1646
1647 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1648 syncRendererState();
1649
1650 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1651 transformValues);
1652}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001653
Sami Väisänend59ca052016-06-21 16:10:00 +03001654void Context::stencilStrokePathInstanced(GLsizei numPaths,
1655 GLenum pathNameType,
1656 const void *paths,
1657 GLuint pathBase,
1658 GLint reference,
1659 GLuint mask,
1660 GLenum transformType,
1661 const GLfloat *transformValues)
1662{
1663 const auto &pathObjects =
1664 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1665
1666 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1667 syncRendererState();
1668
1669 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1670 transformValues);
1671}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001672
Sami Väisänend59ca052016-06-21 16:10:00 +03001673void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1674 GLenum pathNameType,
1675 const void *paths,
1676 GLuint pathBase,
1677 GLenum fillMode,
1678 GLuint mask,
1679 GLenum coverMode,
1680 GLenum transformType,
1681 const GLfloat *transformValues)
1682{
1683 const auto &pathObjects =
1684 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1685
1686 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1687 syncRendererState();
1688
1689 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1690 transformType, transformValues);
1691}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001692
Sami Väisänend59ca052016-06-21 16:10:00 +03001693void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1694 GLenum pathNameType,
1695 const void *paths,
1696 GLuint pathBase,
1697 GLint reference,
1698 GLuint mask,
1699 GLenum coverMode,
1700 GLenum transformType,
1701 const GLfloat *transformValues)
1702{
1703 const auto &pathObjects =
1704 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1705
1706 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1707 syncRendererState();
1708
1709 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1710 transformType, transformValues);
1711}
1712
Sami Väisänen46eaa942016-06-29 10:26:37 +03001713void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1714{
1715 auto *programObject = getProgram(program);
1716
1717 programObject->bindFragmentInputLocation(location, name);
1718}
1719
1720void Context::programPathFragmentInputGen(GLuint program,
1721 GLint location,
1722 GLenum genMode,
1723 GLint components,
1724 const GLfloat *coeffs)
1725{
1726 auto *programObject = getProgram(program);
1727
1728 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1729}
1730
Jamie Madill437fa652016-05-03 15:13:24 -04001731void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001732{
Geoff Langda5777c2014-07-11 09:52:58 -04001733 if (error.isError())
1734 {
1735 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001736
1737 if (!error.getMessage().empty())
1738 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001739 auto *debug = &mGLState.getDebug();
1740 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1741 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001742 }
Geoff Langda5777c2014-07-11 09:52:58 -04001743 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001744}
1745
1746// Get one of the recorded errors and clear its flag, if any.
1747// [OpenGL ES 2.0.24] section 2.5 page 13.
1748GLenum Context::getError()
1749{
Geoff Langda5777c2014-07-11 09:52:58 -04001750 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001751 {
Geoff Langda5777c2014-07-11 09:52:58 -04001752 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001753 }
Geoff Langda5777c2014-07-11 09:52:58 -04001754 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001755 {
Geoff Langda5777c2014-07-11 09:52:58 -04001756 GLenum error = *mErrors.begin();
1757 mErrors.erase(mErrors.begin());
1758 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001759 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001760}
1761
1762GLenum Context::getResetStatus()
1763{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001764 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001765 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001766 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001767 // mResetStatus will be set by the markContextLost callback
1768 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001769 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001770 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001771 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001772 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001773 }
1774
1775 GLenum status = mResetStatus;
1776
1777 if (mResetStatus != GL_NO_ERROR)
1778 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001779 ASSERT(mContextLost);
1780
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001781 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001782 {
1783 mResetStatus = GL_NO_ERROR;
1784 }
1785 }
Jamie Madill893ab082014-05-16 16:56:10 -04001786
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001787 return status;
1788}
1789
1790bool Context::isResetNotificationEnabled()
1791{
1792 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1793}
1794
Corentin Walleze3b10e82015-05-20 11:06:25 -04001795const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001796{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001797 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001798}
1799
1800EGLenum Context::getClientType() const
1801{
1802 return mClientType;
1803}
1804
1805EGLenum Context::getRenderBuffer() const
1806{
Corentin Wallez37c39792015-08-20 14:19:46 -04001807 auto framebufferIt = mFramebufferMap.find(0);
1808 if (framebufferIt != mFramebufferMap.end())
1809 {
1810 const Framebuffer *framebuffer = framebufferIt->second;
1811 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1812
1813 ASSERT(backAttachment != nullptr);
1814 return backAttachment->getSurface()->getRenderBuffer();
1815 }
1816 else
1817 {
1818 return EGL_NONE;
1819 }
Régis Fénéon83107972015-02-05 12:57:44 +01001820}
1821
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001822VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001823{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001824 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001825 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1826 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001827 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001828 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1829
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001830 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001831 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001832
1833 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001834}
1835
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001836TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001837{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001838 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001839 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1840 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001841 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001842 transformFeedback =
1843 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001844 transformFeedback->addRef();
1845 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001846 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001847
1848 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001849}
1850
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001851Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1852{
1853 // Can be called from Bind without a prior call to Gen.
1854 auto framebufferIt = mFramebufferMap.find(framebuffer);
1855 bool neverCreated = framebufferIt == mFramebufferMap.end();
1856 if (neverCreated || framebufferIt->second == nullptr)
1857 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001858 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001859 if (neverCreated)
1860 {
1861 mFramebufferHandleAllocator.reserve(framebuffer);
1862 mFramebufferMap[framebuffer] = newFBO;
1863 return newFBO;
1864 }
1865
1866 framebufferIt->second = newFBO;
1867 }
1868
1869 return framebufferIt->second;
1870}
1871
Geoff Lang36167ab2015-12-07 10:27:14 -05001872bool Context::isVertexArrayGenerated(GLuint vertexArray)
1873{
1874 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1875}
1876
1877bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1878{
1879 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1880}
1881
Shannon Woods53a94a82014-06-24 15:20:36 -04001882void Context::detachTexture(GLuint texture)
1883{
1884 // Simple pass-through to State's detachTexture method, as textures do not require
1885 // allocation map management either here or in the resource manager at detach time.
1886 // Zero textures are held by the Context, and we don't attempt to request them from
1887 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001888 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001889}
1890
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001891void Context::detachBuffer(GLuint buffer)
1892{
Yuly Novikov5807a532015-12-03 13:01:22 -05001893 // Simple pass-through to State's detachBuffer method, since
1894 // only buffer attachments to container objects that are bound to the current context
1895 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001896
Yuly Novikov5807a532015-12-03 13:01:22 -05001897 // [OpenGL ES 3.2] section 5.1.2 page 45:
1898 // Attachments to unbound container objects, such as
1899 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1900 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001901 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001902}
1903
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001904void Context::detachFramebuffer(GLuint framebuffer)
1905{
Shannon Woods53a94a82014-06-24 15:20:36 -04001906 // Framebuffer detachment is handled by Context, because 0 is a valid
1907 // Framebuffer object, and a pointer to it must be passed from Context
1908 // to State at binding time.
1909
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001910 // [OpenGL ES 2.0.24] section 4.4 page 107:
1911 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1912 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1913
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001914 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001915 {
1916 bindReadFramebuffer(0);
1917 }
1918
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001919 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001920 {
1921 bindDrawFramebuffer(0);
1922 }
1923}
1924
1925void Context::detachRenderbuffer(GLuint renderbuffer)
1926{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001927 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001928}
1929
Jamie Madill57a89722013-07-02 11:57:03 -04001930void Context::detachVertexArray(GLuint vertexArray)
1931{
Jamie Madill77a72f62015-04-14 11:18:32 -04001932 // Vertex array detachment is handled by Context, because 0 is a valid
1933 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001934 // binding time.
1935
Jamie Madill57a89722013-07-02 11:57:03 -04001936 // [OpenGL ES 3.0.2] section 2.10 page 43:
1937 // If a vertex array object that is currently bound is deleted, the binding
1938 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001939 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001940 {
1941 bindVertexArray(0);
1942 }
1943}
1944
Geoff Langc8058452014-02-03 12:04:11 -05001945void Context::detachTransformFeedback(GLuint transformFeedback)
1946{
Corentin Walleza2257da2016-04-19 16:43:12 -04001947 // Transform feedback detachment is handled by Context, because 0 is a valid
1948 // transform feedback, and a pointer to it must be passed from Context to State at
1949 // binding time.
1950
1951 // The OpenGL specification doesn't mention what should happen when the currently bound
1952 // transform feedback object is deleted. Since it is a container object, we treat it like
1953 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001954 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04001955 {
1956 bindTransformFeedback(0);
1957 }
Geoff Langc8058452014-02-03 12:04:11 -05001958}
1959
Jamie Madilldc356042013-07-19 16:36:57 -04001960void Context::detachSampler(GLuint sampler)
1961{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001962 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001963}
1964
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001965void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1966{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001967 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001968}
1969
Jamie Madille29d1672013-07-19 16:36:57 -04001970void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1971{
Jamie Madill901b3792016-05-26 09:20:40 -04001972 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001973
1974 Sampler *samplerObject = getSampler(sampler);
1975 ASSERT(samplerObject);
1976
Geoff Lang69cce582015-09-17 13:20:36 -04001977 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001978 switch (pname)
1979 {
Geoff Lang69cce582015-09-17 13:20:36 -04001980 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1981 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1982 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1983 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1984 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1985 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1986 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1987 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1988 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1989 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1990 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001991 }
Geoff Lang69cce582015-09-17 13:20:36 -04001992 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001993}
1994
1995void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1996{
Jamie Madill901b3792016-05-26 09:20:40 -04001997 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001998
1999 Sampler *samplerObject = getSampler(sampler);
2000 ASSERT(samplerObject);
2001
Geoff Lang69cce582015-09-17 13:20:36 -04002002 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002003 switch (pname)
2004 {
Geoff Lang69cce582015-09-17 13:20:36 -04002005 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2006 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2007 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2008 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2009 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2010 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2011 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2012 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2013 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2014 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2015 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002016 }
Geoff Lang69cce582015-09-17 13:20:36 -04002017 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002018}
2019
Jamie Madill9675b802013-07-19 16:36:59 -04002020GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2021{
Jamie Madill901b3792016-05-26 09:20:40 -04002022 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002023
2024 Sampler *samplerObject = getSampler(sampler);
2025 ASSERT(samplerObject);
2026
Geoff Lang69cce582015-09-17 13:20:36 -04002027 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002028 switch (pname)
2029 {
Geoff Lang69cce582015-09-17 13:20:36 -04002030 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2031 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2032 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2033 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2034 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2035 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002036 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2037 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002038 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2039 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2040 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002041 }
Geoff Lang69cce582015-09-17 13:20:36 -04002042 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002043}
2044
2045GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2046{
Jamie Madill901b3792016-05-26 09:20:40 -04002047 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002048
2049 Sampler *samplerObject = getSampler(sampler);
2050 ASSERT(samplerObject);
2051
Geoff Lang69cce582015-09-17 13:20:36 -04002052 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002053 switch (pname)
2054 {
Geoff Lang69cce582015-09-17 13:20:36 -04002055 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2056 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2057 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2058 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2059 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2060 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2061 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2062 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2063 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2064 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2065 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002066 }
Geoff Lang69cce582015-09-17 13:20:36 -04002067 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002068}
2069
Olli Etuahof0fee072016-03-30 15:11:58 +03002070void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2071{
2072 gl::Program *programObject = getProgram(program);
2073 ASSERT(programObject != nullptr);
2074
2075 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2076 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2077}
2078
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002079void Context::initRendererString()
2080{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002081 std::ostringstream rendererString;
2082 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002083 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002084 rendererString << ")";
2085
Geoff Langcec35902014-04-16 10:52:36 -04002086 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002087}
2088
Geoff Langc0b9ef42014-07-02 10:02:37 -04002089const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002090{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002091 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002092}
2093
Geoff Langcec35902014-04-16 10:52:36 -04002094void Context::initExtensionStrings()
2095{
Geoff Lang493daf52014-07-03 13:38:44 -04002096 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002097
Geoff Langc0b9ef42014-07-02 10:02:37 -04002098 std::ostringstream combinedStringStream;
2099 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2100 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002101}
2102
Geoff Langc0b9ef42014-07-02 10:02:37 -04002103const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002104{
2105 return mExtensionString;
2106}
2107
Geoff Langc0b9ef42014-07-02 10:02:37 -04002108const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002109{
2110 return mExtensionStrings[idx];
2111}
2112
2113size_t Context::getExtensionStringCount() const
2114{
2115 return mExtensionStrings.size();
2116}
2117
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002118void Context::beginTransformFeedback(GLenum primitiveMode)
2119{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002120 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002121 ASSERT(transformFeedback != nullptr);
2122 ASSERT(!transformFeedback->isPaused());
2123
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002124 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002125}
2126
2127bool Context::hasActiveTransformFeedback(GLuint program) const
2128{
2129 for (auto pair : mTransformFeedbackMap)
2130 {
2131 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2132 {
2133 return true;
2134 }
2135 }
2136 return false;
2137}
2138
Jamie Madill00ed7a12016-05-19 13:13:38 -04002139void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002140{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002141 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002142
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002143 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002144
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002145 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002146
Jamie Madill00ed7a12016-05-19 13:13:38 -04002147 if (mClientVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002148 {
2149 // Disable ES3+ extensions
2150 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002151 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002152 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002153 }
2154
Jamie Madill00ed7a12016-05-19 13:13:38 -04002155 if (mClientVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002156 {
2157 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2158 //mExtensions.sRGB = false;
2159 }
2160
Jamie Madill00ed7a12016-05-19 13:13:38 -04002161 // Some extensions are always available because they are implemented in the GL layer.
2162 mExtensions.bindUniformLocation = true;
2163 mExtensions.vertexArrayObject = true;
2164
2165 // Enable the no error extension if the context was created with the flag.
2166 mExtensions.noError = mSkipValidation;
2167
Geoff Lang70d0f492015-12-10 17:45:46 -05002168 // Explicitly enable GL_KHR_debug
2169 mExtensions.debug = true;
2170 mExtensions.maxDebugMessageLength = 1024;
2171 mExtensions.maxDebugLoggedMessages = 1024;
2172 mExtensions.maxDebugGroupStackDepth = 1024;
2173 mExtensions.maxLabelLength = 1024;
2174
Geoff Lang301d1612014-07-09 10:34:37 -04002175 // Apply implementation limits
2176 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002177 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2178 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2179
2180 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002181
Geoff Lang900013c2014-07-07 11:32:19 -04002182 mCaps.compressedTextureFormats.clear();
2183
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002184 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002185 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2186 {
2187 GLenum format = i->first;
2188 TextureCaps formatCaps = i->second;
2189
Geoff Lang5d601382014-07-22 15:14:06 -04002190 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002191
Geoff Lang0d8b7242015-09-09 14:56:53 -04002192 // Update the format caps based on the client version and extensions.
2193 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2194 // ES3.
2195 formatCaps.texturable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002196 formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002197 formatCaps.renderable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002198 formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002199 formatCaps.filterable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002200 formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002201
2202 // OpenGL ES does not support multisampling with integer formats
2203 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002204 {
Geoff Langd87878e2014-09-19 15:42:59 -04002205 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002206 }
Geoff Langd87878e2014-09-19 15:42:59 -04002207
2208 if (formatCaps.texturable && formatInfo.compressed)
2209 {
2210 mCaps.compressedTextureFormats.push_back(format);
2211 }
2212
2213 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002214 }
2215}
2216
Jamie Madill1b94d432015-08-07 13:23:23 -04002217void Context::syncRendererState()
2218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002219 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2220 mImplementation->syncState(mGLState, dirtyBits);
2221 mGLState.clearDirtyBits();
2222 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002223}
2224
Jamie Madillad9f24e2016-02-12 09:27:24 -05002225void Context::syncRendererState(const State::DirtyBits &bitMask,
2226 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002227{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002228 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2229 mImplementation->syncState(mGLState, dirtyBits);
2230 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002231
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002232 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002233}
Jamie Madillc29968b2016-01-20 11:17:23 -05002234
2235void Context::blitFramebuffer(GLint srcX0,
2236 GLint srcY0,
2237 GLint srcX1,
2238 GLint srcY1,
2239 GLint dstX0,
2240 GLint dstY0,
2241 GLint dstX1,
2242 GLint dstY1,
2243 GLbitfield mask,
2244 GLenum filter)
2245{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002246 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002247 ASSERT(drawFramebuffer);
2248
2249 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2250 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2251
Jamie Madillad9f24e2016-02-12 09:27:24 -05002252 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002253
Jamie Madill8415b5f2016-04-26 13:41:39 -04002254 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002255}
Jamie Madillc29968b2016-01-20 11:17:23 -05002256
2257void Context::clear(GLbitfield mask)
2258{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002259 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002260 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002261}
2262
2263void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2264{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002265 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002266 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2267 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002268}
2269
2270void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2271{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002272 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002273 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2274 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002275}
2276
2277void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2278{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002279 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002280 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2281 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002282}
2283
2284void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2285{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002286 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002287 ASSERT(framebufferObject);
2288
2289 // If a buffer is not present, the clear has no effect
2290 if (framebufferObject->getDepthbuffer() == nullptr &&
2291 framebufferObject->getStencilbuffer() == nullptr)
2292 {
2293 return;
2294 }
2295
Jamie Madillad9f24e2016-02-12 09:27:24 -05002296 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002297 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2298 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002299}
2300
2301void Context::readPixels(GLint x,
2302 GLint y,
2303 GLsizei width,
2304 GLsizei height,
2305 GLenum format,
2306 GLenum type,
2307 GLvoid *pixels)
2308{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002309 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002310
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002311 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002312 ASSERT(framebufferObject);
2313
2314 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002315 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002316}
2317
2318void Context::copyTexImage2D(GLenum target,
2319 GLint level,
2320 GLenum internalformat,
2321 GLint x,
2322 GLint y,
2323 GLsizei width,
2324 GLsizei height,
2325 GLint border)
2326{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002327 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002328 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002329
Jamie Madillc29968b2016-01-20 11:17:23 -05002330 Rectangle sourceArea(x, y, width, height);
2331
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002332 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002333 Texture *texture =
2334 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002335 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002336}
2337
2338void Context::copyTexSubImage2D(GLenum target,
2339 GLint level,
2340 GLint xoffset,
2341 GLint yoffset,
2342 GLint x,
2343 GLint y,
2344 GLsizei width,
2345 GLsizei height)
2346{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002347 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002348 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002349
Jamie Madillc29968b2016-01-20 11:17:23 -05002350 Offset destOffset(xoffset, yoffset, 0);
2351 Rectangle sourceArea(x, y, width, height);
2352
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002353 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002354 Texture *texture =
2355 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002356 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002357}
2358
2359void Context::copyTexSubImage3D(GLenum target,
2360 GLint level,
2361 GLint xoffset,
2362 GLint yoffset,
2363 GLint zoffset,
2364 GLint x,
2365 GLint y,
2366 GLsizei width,
2367 GLsizei height)
2368{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002369 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002370 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002371
Jamie Madillc29968b2016-01-20 11:17:23 -05002372 Offset destOffset(xoffset, yoffset, zoffset);
2373 Rectangle sourceArea(x, y, width, height);
2374
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002375 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002376 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002377 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002378}
2379
2380void Context::framebufferTexture2D(GLenum target,
2381 GLenum attachment,
2382 GLenum textarget,
2383 GLuint texture,
2384 GLint level)
2385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002386 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002387 ASSERT(framebuffer);
2388
2389 if (texture != 0)
2390 {
2391 Texture *textureObj = getTexture(texture);
2392
2393 ImageIndex index = ImageIndex::MakeInvalid();
2394
2395 if (textarget == GL_TEXTURE_2D)
2396 {
2397 index = ImageIndex::Make2D(level);
2398 }
2399 else
2400 {
2401 ASSERT(IsCubeMapTextureTarget(textarget));
2402 index = ImageIndex::MakeCube(textarget, level);
2403 }
2404
2405 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2406 }
2407 else
2408 {
2409 framebuffer->resetAttachment(attachment);
2410 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002411
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002412 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002413}
2414
2415void Context::framebufferRenderbuffer(GLenum target,
2416 GLenum attachment,
2417 GLenum renderbuffertarget,
2418 GLuint renderbuffer)
2419{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002420 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002421 ASSERT(framebuffer);
2422
2423 if (renderbuffer != 0)
2424 {
2425 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2426 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2427 renderbufferObject);
2428 }
2429 else
2430 {
2431 framebuffer->resetAttachment(attachment);
2432 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002433
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002434 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002435}
2436
2437void Context::framebufferTextureLayer(GLenum target,
2438 GLenum attachment,
2439 GLuint texture,
2440 GLint level,
2441 GLint layer)
2442{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002443 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002444 ASSERT(framebuffer);
2445
2446 if (texture != 0)
2447 {
2448 Texture *textureObject = getTexture(texture);
2449
2450 ImageIndex index = ImageIndex::MakeInvalid();
2451
2452 if (textureObject->getTarget() == GL_TEXTURE_3D)
2453 {
2454 index = ImageIndex::Make3D(level, layer);
2455 }
2456 else
2457 {
2458 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2459 index = ImageIndex::Make2DArray(level, layer);
2460 }
2461
2462 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2463 }
2464 else
2465 {
2466 framebuffer->resetAttachment(attachment);
2467 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002468
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002469 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002470}
2471
2472void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002474 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002475 ASSERT(framebuffer);
2476 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002477 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002478}
2479
2480void Context::readBuffer(GLenum mode)
2481{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002482 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002484 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002485}
2486
2487void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2488{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002489 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002490 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002491
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002492 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 ASSERT(framebuffer);
2494
2495 // The specification isn't clear what should be done when the framebuffer isn't complete.
2496 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002497 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002498}
2499
2500void Context::invalidateFramebuffer(GLenum target,
2501 GLsizei numAttachments,
2502 const GLenum *attachments)
2503{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002504 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002505 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002506
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002507 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002508 ASSERT(framebuffer);
2509
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002510 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002511 {
Jamie Madill437fa652016-05-03 15:13:24 -04002512 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002513 }
Jamie Madill437fa652016-05-03 15:13:24 -04002514
2515 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002516}
2517
2518void Context::invalidateSubFramebuffer(GLenum target,
2519 GLsizei numAttachments,
2520 const GLenum *attachments,
2521 GLint x,
2522 GLint y,
2523 GLsizei width,
2524 GLsizei height)
2525{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002526 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002527 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002528
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002529 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002530 ASSERT(framebuffer);
2531
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002532 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002533 {
Jamie Madill437fa652016-05-03 15:13:24 -04002534 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002535 }
Jamie Madill437fa652016-05-03 15:13:24 -04002536
2537 Rectangle area(x, y, width, height);
2538 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002539}
2540
Jamie Madill73a84962016-02-12 09:27:23 -05002541void Context::texImage2D(GLenum target,
2542 GLint level,
2543 GLint internalformat,
2544 GLsizei width,
2545 GLsizei height,
2546 GLint border,
2547 GLenum format,
2548 GLenum type,
2549 const GLvoid *pixels)
2550{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002551 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002552
2553 Extents size(width, height, 1);
2554 Texture *texture =
2555 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002556 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002557 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002558}
2559
2560void Context::texImage3D(GLenum target,
2561 GLint level,
2562 GLint internalformat,
2563 GLsizei width,
2564 GLsizei height,
2565 GLsizei depth,
2566 GLint border,
2567 GLenum format,
2568 GLenum type,
2569 const GLvoid *pixels)
2570{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002571 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002572
2573 Extents size(width, height, depth);
2574 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002575 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002576 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002577}
2578
2579void Context::texSubImage2D(GLenum target,
2580 GLint level,
2581 GLint xoffset,
2582 GLint yoffset,
2583 GLsizei width,
2584 GLsizei height,
2585 GLenum format,
2586 GLenum type,
2587 const GLvoid *pixels)
2588{
2589 // Zero sized uploads are valid but no-ops
2590 if (width == 0 || height == 0)
2591 {
2592 return;
2593 }
2594
Jamie Madillad9f24e2016-02-12 09:27:24 -05002595 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002596
2597 Box area(xoffset, yoffset, 0, width, height, 1);
2598 Texture *texture =
2599 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002600 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002601 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002602}
2603
2604void Context::texSubImage3D(GLenum target,
2605 GLint level,
2606 GLint xoffset,
2607 GLint yoffset,
2608 GLint zoffset,
2609 GLsizei width,
2610 GLsizei height,
2611 GLsizei depth,
2612 GLenum format,
2613 GLenum type,
2614 const GLvoid *pixels)
2615{
2616 // Zero sized uploads are valid but no-ops
2617 if (width == 0 || height == 0 || depth == 0)
2618 {
2619 return;
2620 }
2621
Jamie Madillad9f24e2016-02-12 09:27:24 -05002622 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002623
2624 Box area(xoffset, yoffset, zoffset, width, height, depth);
2625 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002627 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002628}
2629
2630void Context::compressedTexImage2D(GLenum target,
2631 GLint level,
2632 GLenum internalformat,
2633 GLsizei width,
2634 GLsizei height,
2635 GLint border,
2636 GLsizei imageSize,
2637 const GLvoid *data)
2638{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002639 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002640
2641 Extents size(width, height, 1);
2642 Texture *texture =
2643 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002644 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2645 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002646 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002647}
2648
2649void Context::compressedTexImage3D(GLenum target,
2650 GLint level,
2651 GLenum internalformat,
2652 GLsizei width,
2653 GLsizei height,
2654 GLsizei depth,
2655 GLint border,
2656 GLsizei imageSize,
2657 const GLvoid *data)
2658{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002659 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002660
2661 Extents size(width, height, depth);
2662 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002663 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2664 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002665 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002666}
2667
2668void Context::compressedTexSubImage2D(GLenum target,
2669 GLint level,
2670 GLint xoffset,
2671 GLint yoffset,
2672 GLsizei width,
2673 GLsizei height,
2674 GLenum format,
2675 GLsizei imageSize,
2676 const GLvoid *data)
2677{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002678 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002679
2680 Box area(xoffset, yoffset, 0, width, height, 1);
2681 Texture *texture =
2682 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2684 format, imageSize,
2685 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002686}
2687
2688void Context::compressedTexSubImage3D(GLenum target,
2689 GLint level,
2690 GLint xoffset,
2691 GLint yoffset,
2692 GLint zoffset,
2693 GLsizei width,
2694 GLsizei height,
2695 GLsizei depth,
2696 GLenum format,
2697 GLsizei imageSize,
2698 const GLvoid *data)
2699{
2700 // Zero sized uploads are valid but no-ops
2701 if (width == 0 || height == 0)
2702 {
2703 return;
2704 }
2705
Jamie Madillad9f24e2016-02-12 09:27:24 -05002706 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002707
2708 Box area(xoffset, yoffset, zoffset, width, height, depth);
2709 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002710 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2711 format, imageSize,
2712 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002713}
2714
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002715void Context::generateMipmap(GLenum target)
2716{
2717 Texture *texture = getTargetTexture(target);
2718 handleError(texture->generateMipmap());
2719}
2720
Olli Etuaho4f667482016-03-30 15:56:35 +03002721void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2722{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002723 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002724 ASSERT(buffer);
2725
2726 if (!buffer->isMapped())
2727 {
2728 *params = nullptr;
2729 }
2730 else
2731 {
2732 *params = buffer->getMapPointer();
2733 }
2734}
2735
2736GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2737{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002738 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002739 ASSERT(buffer);
2740
2741 Error error = buffer->map(access);
2742 if (error.isError())
2743 {
Jamie Madill437fa652016-05-03 15:13:24 -04002744 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002745 return nullptr;
2746 }
2747
2748 return buffer->getMapPointer();
2749}
2750
2751GLboolean Context::unmapBuffer(GLenum target)
2752{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002753 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002754 ASSERT(buffer);
2755
2756 GLboolean result;
2757 Error error = buffer->unmap(&result);
2758 if (error.isError())
2759 {
Jamie Madill437fa652016-05-03 15:13:24 -04002760 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002761 return GL_FALSE;
2762 }
2763
2764 return result;
2765}
2766
2767GLvoid *Context::mapBufferRange(GLenum target,
2768 GLintptr offset,
2769 GLsizeiptr length,
2770 GLbitfield access)
2771{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002772 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002773 ASSERT(buffer);
2774
2775 Error error = buffer->mapRange(offset, length, access);
2776 if (error.isError())
2777 {
Jamie Madill437fa652016-05-03 15:13:24 -04002778 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002779 return nullptr;
2780 }
2781
2782 return buffer->getMapPointer();
2783}
2784
2785void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2786{
2787 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2788}
2789
Jamie Madillad9f24e2016-02-12 09:27:24 -05002790void Context::syncStateForReadPixels()
2791{
2792 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2793}
2794
2795void Context::syncStateForTexImage()
2796{
2797 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2798}
2799
2800void Context::syncStateForClear()
2801{
2802 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2803}
2804
2805void Context::syncStateForBlit()
2806{
2807 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2808}
2809
Jamie Madillc20ab272016-06-09 07:20:46 -07002810void Context::activeTexture(GLenum texture)
2811{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002812 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002813}
2814
2815void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2816{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002817 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07002818}
2819
2820void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2821{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002822 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002823}
2824
2825void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2826{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002828}
2829
2830void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2831{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002833}
2834
2835void Context::clearDepthf(GLclampf depth)
2836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07002838}
2839
2840void Context::clearStencil(GLint s)
2841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07002843}
2844
2845void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2846{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002847 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002848}
2849
2850void Context::cullFace(GLenum mode)
2851{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002852 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002853}
2854
2855void Context::depthFunc(GLenum func)
2856{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002857 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07002858}
2859
2860void Context::depthMask(GLboolean flag)
2861{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002862 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002863}
2864
2865void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2866{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002867 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07002868}
2869
2870void Context::disable(GLenum cap)
2871{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002872 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002873}
2874
2875void Context::disableVertexAttribArray(GLuint index)
2876{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002877 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002878}
2879
2880void Context::enable(GLenum cap)
2881{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002882 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002883}
2884
2885void Context::enableVertexAttribArray(GLuint index)
2886{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002887 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002888}
2889
2890void Context::frontFace(GLenum mode)
2891{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002892 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002893}
2894
2895void Context::hint(GLenum target, GLenum mode)
2896{
2897 switch (target)
2898 {
2899 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002900 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002901 break;
2902
2903 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002904 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002905 break;
2906
2907 default:
2908 UNREACHABLE();
2909 return;
2910 }
2911}
2912
2913void Context::lineWidth(GLfloat width)
2914{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002915 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07002916}
2917
2918void Context::pixelStorei(GLenum pname, GLint param)
2919{
2920 switch (pname)
2921 {
2922 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002923 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002924 break;
2925
2926 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002927 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002928 break;
2929
2930 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002931 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002932 break;
2933
2934 case GL_UNPACK_ROW_LENGTH:
2935 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002936 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002937 break;
2938
2939 case GL_UNPACK_IMAGE_HEIGHT:
2940 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002942 break;
2943
2944 case GL_UNPACK_SKIP_IMAGES:
2945 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002946 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002947 break;
2948
2949 case GL_UNPACK_SKIP_ROWS:
2950 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002951 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002952 break;
2953
2954 case GL_UNPACK_SKIP_PIXELS:
2955 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002956 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002957 break;
2958
2959 case GL_PACK_ROW_LENGTH:
2960 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002961 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002962 break;
2963
2964 case GL_PACK_SKIP_ROWS:
2965 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002966 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002967 break;
2968
2969 case GL_PACK_SKIP_PIXELS:
2970 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002971 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002972 break;
2973
2974 default:
2975 UNREACHABLE();
2976 return;
2977 }
2978}
2979
2980void Context::polygonOffset(GLfloat factor, GLfloat units)
2981{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002982 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07002983}
2984
2985void Context::sampleCoverage(GLclampf value, GLboolean invert)
2986{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002987 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002988}
2989
2990void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2991{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002992 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002993}
2994
2995void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2996{
2997 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2998 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002999 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003000 }
3001
3002 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3003 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003004 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003005 }
3006}
3007
3008void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3009{
3010 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3011 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003012 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003013 }
3014
3015 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3016 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003017 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003018 }
3019}
3020
3021void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3022{
3023 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3024 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003025 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003026 }
3027
3028 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3029 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003030 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003031 }
3032}
3033
3034void Context::vertexAttrib1f(GLuint index, GLfloat x)
3035{
3036 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003037 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003038}
3039
3040void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3041{
3042 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003043 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003044}
3045
3046void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3047{
3048 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003049 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003050}
3051
3052void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3053{
3054 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003055 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003056}
3057
3058void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3059{
3060 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003061 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003062}
3063
3064void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3065{
3066 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003067 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003068}
3069
3070void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3071{
3072 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003073 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003074}
3075
3076void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3077{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003078 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003079}
3080
3081void Context::vertexAttribPointer(GLuint index,
3082 GLint size,
3083 GLenum type,
3084 GLboolean normalized,
3085 GLsizei stride,
3086 const GLvoid *ptr)
3087{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003088 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3089 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003090}
3091
3092void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3093{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003095}
3096
3097void Context::vertexAttribIPointer(GLuint index,
3098 GLint size,
3099 GLenum type,
3100 GLsizei stride,
3101 const GLvoid *pointer)
3102{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003103 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3104 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003105}
3106
3107void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3108{
3109 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003110 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003111}
3112
3113void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3114{
3115 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003116 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003117}
3118
3119void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3120{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003121 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003122}
3123
3124void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3125{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003126 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003127}
3128
3129void Context::debugMessageControl(GLenum source,
3130 GLenum type,
3131 GLenum severity,
3132 GLsizei count,
3133 const GLuint *ids,
3134 GLboolean enabled)
3135{
3136 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003137 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3138 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003139}
3140
3141void Context::debugMessageInsert(GLenum source,
3142 GLenum type,
3143 GLuint id,
3144 GLenum severity,
3145 GLsizei length,
3146 const GLchar *buf)
3147{
3148 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003149 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003150}
3151
3152void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3153{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003154 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003155}
3156
3157GLuint Context::getDebugMessageLog(GLuint count,
3158 GLsizei bufSize,
3159 GLenum *sources,
3160 GLenum *types,
3161 GLuint *ids,
3162 GLenum *severities,
3163 GLsizei *lengths,
3164 GLchar *messageLog)
3165{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003166 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3167 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003168}
3169
3170void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3171{
3172 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003173 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003174}
3175
3176void Context::popDebugGroup()
3177{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003178 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003179}
3180
Jamie Madillc29968b2016-01-20 11:17:23 -05003181} // namespace gl