blob: 933082f393fcc29fa423e2537a23ff9ae0444b16 [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>
14
Geoff Lang0b7eef72014-06-12 14:10:47 -040015#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050016#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050018#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050019#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Fence.h"
21#include "libANGLE/Framebuffer.h"
22#include "libANGLE/FramebufferAttachment.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050025#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050026#include "libANGLE/ResourceManager.h"
27#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050028#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Texture.h"
30#include "libANGLE/TransformFeedback.h"
31#include "libANGLE/VertexArray.h"
32#include "libANGLE/formatutils.h"
33#include "libANGLE/validationES.h"
Jamie Madill437fa652016-05-03 15:13:24 -040034#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040035#include "libANGLE/renderer/EGLImplFactory.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000036
Geoff Langf6db0982015-08-25 13:04:00 -040037namespace
38{
39
Ian Ewell3ffd78b2016-01-22 16:09:42 -050040template <typename T>
41gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
42{
43 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
44 ASSERT(queryObject != nullptr);
45
46 switch (pname)
47 {
48 case GL_QUERY_RESULT_EXT:
49 return queryObject->getResult(params);
50 case GL_QUERY_RESULT_AVAILABLE_EXT:
51 {
52 bool available;
53 gl::Error error = queryObject->isResultAvailable(&available);
54 if (!error.isError())
55 {
56 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
57 }
58 return error;
59 }
60 default:
61 UNREACHABLE();
62 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
63 }
64}
65
Geoff Langf6db0982015-08-25 13:04:00 -040066void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
67{
Geoff Lang1a683462015-09-29 15:09:59 -040068 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040069 {
70 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
71 tfBufferIndex++)
72 {
73 const OffsetBindingPointer<gl::Buffer> &buffer =
74 transformFeedback->getIndexedBuffer(tfBufferIndex);
75 if (buffer.get() != nullptr)
76 {
77 buffer->onTransformFeedback();
78 }
79 }
80 }
81}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050082
83// Attribute map queries.
84EGLint GetClientVersion(const egl::AttributeMap &attribs)
85{
Ian Ewellec2c0c52016-04-05 13:46:26 -040086 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -050087}
88
89GLenum GetResetStrategy(const egl::AttributeMap &attribs)
90{
Ian Ewellec2c0c52016-04-05 13:46:26 -040091 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
92 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -050093 switch (attrib)
94 {
95 case EGL_NO_RESET_NOTIFICATION:
96 return GL_NO_RESET_NOTIFICATION_EXT;
97 case EGL_LOSE_CONTEXT_ON_RESET:
98 return GL_LOSE_CONTEXT_ON_RESET_EXT;
99 default:
100 UNREACHABLE();
101 return GL_NONE;
102 }
103}
104
105bool GetRobustAccess(const egl::AttributeMap &attribs)
106{
107 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
108}
109
110bool GetDebug(const egl::AttributeMap &attribs)
111{
112 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
113}
114
115bool GetNoError(const egl::AttributeMap &attribs)
116{
117 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
118}
119
Geoff Langf6db0982015-08-25 13:04:00 -0400120} // anonymous namespace
121
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000122namespace gl
123{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000124
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400125Context::Context(rx::EGLImplFactory *implFactory,
126 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400127 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500128 const egl::AttributeMap &attribs)
129 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500130 mState,
131 mCaps,
132 mTextureCaps,
133 mExtensions,
134 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500135 mLimitations,
136 GetNoError(attribs)),
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400137 mImplementation(implFactory->createContext(getData())),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mCompiler(nullptr),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400140 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141 mClientType(EGL_OPENGL_ES_API),
142 mHasBeenCurrent(false),
143 mContextLost(false),
144 mResetStatus(GL_NO_ERROR),
145 mResetStrategy(GetResetStrategy(attribs)),
146 mRobustAccess(GetRobustAccess(attribs)),
147 mCurrentSurface(nullptr),
148 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000149{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500150 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000151
Jamie Madill00ed7a12016-05-19 13:13:38 -0400152 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400153
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500154 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100155
Shannon Woods53a94a82014-06-24 15:20:36 -0400156 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400157
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400158 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000159 {
160 mResourceManager = shareContext->mResourceManager;
161 mResourceManager->addRef();
162 }
163 else
164 {
Jamie Madill901b3792016-05-26 09:20:40 -0400165 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000166 }
167
Jamie Madillc185cb82015-04-28 12:39:08 -0400168 mData.resourceManager = mResourceManager;
169
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000170 // [OpenGL ES 2.0.24] section 3.7 page 83:
171 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
172 // and cube map texture state vectors respectively associated with them.
173 // In order that access to these initial textures not be lost, they are treated as texture
174 // objects all of whose names are 0.
175
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400176 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500177 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500178
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400179 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500180 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400181
182 if (mClientVersion >= 3)
183 {
184 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400185 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500186 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400187
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400188 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500189 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400190 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000191
Ian Ewellbda75592016-04-18 17:25:54 -0400192 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
193 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400194 Texture *zeroTextureExternal =
195 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400196 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
197 }
198
Jamie Madille6382c32014-11-07 15:05:26 -0500199 mState.initializeZeroTextures(mZeroTextures);
200
Jamie Madill57a89722013-07-02 11:57:03 -0400201 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000202 bindArrayBuffer(0);
203 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400204
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205 bindRenderbuffer(0);
206
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000207 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400208 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000209 {
210 bindIndexedUniformBuffer(0, i, 0, -1);
211 }
212
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000213 bindCopyReadBuffer(0);
214 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000215 bindPixelPackBuffer(0);
216 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000217
Geoff Lang1a683462015-09-29 15:09:59 -0400218 if (mClientVersion >= 3)
219 {
220 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
221 // In the initial state, a default transform feedback object is bound and treated as
222 // a transform feedback object with a name of zero. That object is bound any time
223 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400224 bindTransformFeedback(0);
225 }
Geoff Langc8058452014-02-03 12:04:11 -0500226
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400227 mCompiler = new Compiler(mImplementation.get(), getData());
Jamie Madillad9f24e2016-02-12 09:27:24 -0500228
229 // Initialize dirty bit masks
230 // TODO(jmadill): additional ES3 state
231 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
232 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
233 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
234 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
235 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
236 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400237 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500238 // No dirty objects.
239
240 // Readpixels uses the pack state and read FBO
241 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
242 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
243 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
244 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
245 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400246 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500247 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
248
249 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
250 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
251 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
252 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
253 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
254 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
255 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
256 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
257 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
258 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
259 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
260 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
261
262 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
263 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
264 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
265 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400266
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400267 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268}
269
270Context::~Context()
271{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500272 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000273
Corentin Wallez37c39792015-08-20 14:19:46 -0400274 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400276 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400277 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400278 {
279 SafeDelete(framebuffer.second);
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281 }
282
Corentin Wallez80b24112015-08-25 16:41:57 -0400283 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400285 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286 }
287
Corentin Wallez80b24112015-08-25 16:41:57 -0400288 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400290 if (query.second != nullptr)
291 {
292 query.second->release();
293 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294 }
295
Corentin Wallez80b24112015-08-25 16:41:57 -0400296 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400297 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400298 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400299 }
300
Corentin Wallez80b24112015-08-25 16:41:57 -0400301 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500302 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500303 if (transformFeedback.second != nullptr)
304 {
305 transformFeedback.second->release();
306 }
Geoff Langc8058452014-02-03 12:04:11 -0500307 }
308
Jamie Madilldedd7b92014-11-05 16:30:36 -0500309 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
313 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314
Corentin Wallez51706ea2015-08-07 14:39:22 -0400315 if (mCurrentSurface != nullptr)
316 {
317 releaseSurface();
318 }
319
Jamie Madill1e9ae072014-11-06 15:27:21 -0500320 if (mResourceManager)
321 {
322 mResourceManager->release();
323 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500324
325 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326}
327
daniel@transgaming.comad629872012-11-28 19:32:06 +0000328void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329{
Jamie Madill77a72f62015-04-14 11:18:32 -0400330 ASSERT(surface != nullptr);
331
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332 if (!mHasBeenCurrent)
333 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400335 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Shannon Woods53a94a82014-06-24 15:20:36 -0400337 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
338 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000339
340 mHasBeenCurrent = true;
341 }
342
Jamie Madill1b94d432015-08-07 13:23:23 -0400343 // TODO(jmadill): Rework this when we support ContextImpl
344 mState.setAllDirtyBits();
345
Corentin Wallez51706ea2015-08-07 14:39:22 -0400346 if (mCurrentSurface)
347 {
348 releaseSurface();
349 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000350 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400351 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000352
Corentin Wallez37c39792015-08-20 14:19:46 -0400353 // Update default framebuffer, the binding of the previous default
354 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400355 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400356 Framebuffer *newDefault = surface->getDefaultFramebuffer();
357 if (mState.getReadFramebuffer() == nullptr)
358 {
359 mState.setReadFramebufferBinding(newDefault);
360 }
361 if (mState.getDrawFramebuffer() == nullptr)
362 {
363 mState.setDrawFramebufferBinding(newDefault);
364 }
365 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400366 }
Ian Ewell292f0052016-02-04 10:37:32 -0500367
368 // Notify the renderer of a context switch
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400369 mImplementation->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370}
371
Jamie Madill77a72f62015-04-14 11:18:32 -0400372void Context::releaseSurface()
373{
Corentin Wallez37c39792015-08-20 14:19:46 -0400374 ASSERT(mCurrentSurface != nullptr);
375
376 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400377 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400378 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
379 if (mState.getReadFramebuffer() == currentDefault)
380 {
381 mState.setReadFramebufferBinding(nullptr);
382 }
383 if (mState.getDrawFramebuffer() == currentDefault)
384 {
385 mState.setDrawFramebufferBinding(nullptr);
386 }
387 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400388 }
389
Corentin Wallez51706ea2015-08-07 14:39:22 -0400390 mCurrentSurface->setIsCurrent(false);
391 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400392}
393
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000394// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395void Context::markContextLost()
396{
397 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
398 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
399 mContextLost = true;
400}
401
402bool Context::isContextLost()
403{
404 return mContextLost;
405}
406
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407GLuint Context::createBuffer()
408{
409 return mResourceManager->createBuffer();
410}
411
412GLuint Context::createProgram()
413{
Jamie Madill901b3792016-05-26 09:20:40 -0400414 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000415}
416
417GLuint Context::createShader(GLenum type)
418{
Jamie Madill901b3792016-05-26 09:20:40 -0400419 return mResourceManager->createShader(mImplementation.get(),
420 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421}
422
423GLuint Context::createTexture()
424{
425 return mResourceManager->createTexture();
426}
427
428GLuint Context::createRenderbuffer()
429{
430 return mResourceManager->createRenderbuffer();
431}
432
Geoff Lang882033e2014-09-30 11:26:07 -0400433GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400434{
Jamie Madill901b3792016-05-26 09:20:40 -0400435 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400436
Cooper Partind8e62a32015-01-29 15:21:25 -0800437 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400438}
439
Jamie Madill57a89722013-07-02 11:57:03 -0400440GLuint Context::createVertexArray()
441{
Geoff Lang36167ab2015-12-07 10:27:14 -0500442 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
443 mVertexArrayMap[vertexArray] = nullptr;
444 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400445}
446
Jamie Madilldc356042013-07-19 16:36:57 -0400447GLuint Context::createSampler()
448{
449 return mResourceManager->createSampler();
450}
451
Geoff Langc8058452014-02-03 12:04:11 -0500452GLuint Context::createTransformFeedback()
453{
Geoff Lang36167ab2015-12-07 10:27:14 -0500454 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
455 mTransformFeedbackMap[transformFeedback] = nullptr;
456 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500457}
458
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459// Returns an unused framebuffer name
460GLuint Context::createFramebuffer()
461{
462 GLuint handle = mFramebufferHandleAllocator.allocate();
463
464 mFramebufferMap[handle] = NULL;
465
466 return handle;
467}
468
Jamie Madill33dc8432013-07-26 11:55:05 -0400469GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000470{
Jamie Madill33dc8432013-07-26 11:55:05 -0400471 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000472
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400473 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000474
475 return handle;
476}
477
478// Returns an unused query name
479GLuint Context::createQuery()
480{
481 GLuint handle = mQueryHandleAllocator.allocate();
482
483 mQueryMap[handle] = NULL;
484
485 return handle;
486}
487
488void Context::deleteBuffer(GLuint buffer)
489{
490 if (mResourceManager->getBuffer(buffer))
491 {
492 detachBuffer(buffer);
493 }
Jamie Madill893ab082014-05-16 16:56:10 -0400494
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000495 mResourceManager->deleteBuffer(buffer);
496}
497
498void Context::deleteShader(GLuint shader)
499{
500 mResourceManager->deleteShader(shader);
501}
502
503void Context::deleteProgram(GLuint program)
504{
505 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000506}
507
508void Context::deleteTexture(GLuint texture)
509{
510 if (mResourceManager->getTexture(texture))
511 {
512 detachTexture(texture);
513 }
514
515 mResourceManager->deleteTexture(texture);
516}
517
518void Context::deleteRenderbuffer(GLuint renderbuffer)
519{
520 if (mResourceManager->getRenderbuffer(renderbuffer))
521 {
522 detachRenderbuffer(renderbuffer);
523 }
Jamie Madill893ab082014-05-16 16:56:10 -0400524
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000525 mResourceManager->deleteRenderbuffer(renderbuffer);
526}
527
Jamie Madillcd055f82013-07-26 11:55:15 -0400528void Context::deleteFenceSync(GLsync fenceSync)
529{
530 // The spec specifies the underlying Fence object is not deleted until all current
531 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
532 // and since our API is currently designed for being called from a single thread, we can delete
533 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700534 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400535}
536
Jamie Madill57a89722013-07-02 11:57:03 -0400537void Context::deleteVertexArray(GLuint vertexArray)
538{
Geoff Lang36167ab2015-12-07 10:27:14 -0500539 auto iter = mVertexArrayMap.find(vertexArray);
540 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000541 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500542 VertexArray *vertexArrayObject = iter->second;
543 if (vertexArrayObject != nullptr)
544 {
545 detachVertexArray(vertexArray);
546 delete vertexArrayObject;
547 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000548
Geoff Lang36167ab2015-12-07 10:27:14 -0500549 mVertexArrayMap.erase(iter);
550 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400551 }
552}
553
Jamie Madilldc356042013-07-19 16:36:57 -0400554void Context::deleteSampler(GLuint sampler)
555{
556 if (mResourceManager->getSampler(sampler))
557 {
558 detachSampler(sampler);
559 }
560
561 mResourceManager->deleteSampler(sampler);
562}
563
Geoff Langc8058452014-02-03 12:04:11 -0500564void Context::deleteTransformFeedback(GLuint transformFeedback)
565{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500566 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500567 if (iter != mTransformFeedbackMap.end())
568 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500569 TransformFeedback *transformFeedbackObject = iter->second;
570 if (transformFeedbackObject != nullptr)
571 {
572 detachTransformFeedback(transformFeedback);
573 transformFeedbackObject->release();
574 }
575
Geoff Lang50b3fe82015-12-08 14:49:12 +0000576 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500577 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500578 }
579}
580
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000581void Context::deleteFramebuffer(GLuint framebuffer)
582{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500583 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584
585 if (framebufferObject != mFramebufferMap.end())
586 {
587 detachFramebuffer(framebuffer);
588
589 mFramebufferHandleAllocator.release(framebufferObject->first);
590 delete framebufferObject->second;
591 mFramebufferMap.erase(framebufferObject);
592 }
593}
594
Jamie Madill33dc8432013-07-26 11:55:05 -0400595void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000596{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500597 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000598
Jamie Madill33dc8432013-07-26 11:55:05 -0400599 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000600 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400601 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000602 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400603 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000604 }
605}
606
607void Context::deleteQuery(GLuint query)
608{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500609 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000610 if (queryObject != mQueryMap.end())
611 {
612 mQueryHandleAllocator.release(queryObject->first);
613 if (queryObject->second)
614 {
615 queryObject->second->release();
616 }
617 mQueryMap.erase(queryObject);
618 }
619}
620
Geoff Lang70d0f492015-12-10 17:45:46 -0500621Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622{
623 return mResourceManager->getBuffer(handle);
624}
625
Geoff Lang48dcae72014-02-05 16:28:24 -0500626Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627{
628 return mResourceManager->getShader(handle);
629}
630
Geoff Lang48dcae72014-02-05 16:28:24 -0500631Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632{
633 return mResourceManager->getProgram(handle);
634}
635
Jamie Madill570f7c82014-07-03 10:38:54 -0400636Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637{
638 return mResourceManager->getTexture(handle);
639}
640
Geoff Lang70d0f492015-12-10 17:45:46 -0500641Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642{
643 return mResourceManager->getRenderbuffer(handle);
644}
645
Jamie Madillcd055f82013-07-26 11:55:15 -0400646FenceSync *Context::getFenceSync(GLsync handle) const
647{
Minmin Gong794e0002015-04-07 18:31:54 -0700648 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400649}
650
Jamie Madill57a89722013-07-02 11:57:03 -0400651VertexArray *Context::getVertexArray(GLuint handle) const
652{
653 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500654 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400655}
656
Jamie Madilldc356042013-07-19 16:36:57 -0400657Sampler *Context::getSampler(GLuint handle) const
658{
659 return mResourceManager->getSampler(handle);
660}
661
Geoff Langc8058452014-02-03 12:04:11 -0500662TransformFeedback *Context::getTransformFeedback(GLuint handle) const
663{
Geoff Lang36167ab2015-12-07 10:27:14 -0500664 auto iter = mTransformFeedbackMap.find(handle);
665 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500666}
667
Geoff Lang70d0f492015-12-10 17:45:46 -0500668LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
669{
670 switch (identifier)
671 {
672 case GL_BUFFER:
673 return getBuffer(name);
674 case GL_SHADER:
675 return getShader(name);
676 case GL_PROGRAM:
677 return getProgram(name);
678 case GL_VERTEX_ARRAY:
679 return getVertexArray(name);
680 case GL_QUERY:
681 return getQuery(name);
682 case GL_TRANSFORM_FEEDBACK:
683 return getTransformFeedback(name);
684 case GL_SAMPLER:
685 return getSampler(name);
686 case GL_TEXTURE:
687 return getTexture(name);
688 case GL_RENDERBUFFER:
689 return getRenderbuffer(name);
690 case GL_FRAMEBUFFER:
691 return getFramebuffer(name);
692 default:
693 UNREACHABLE();
694 return nullptr;
695 }
696}
697
698LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
699{
700 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
701}
702
Jamie Madilldc356042013-07-19 16:36:57 -0400703bool Context::isSampler(GLuint samplerName) const
704{
705 return mResourceManager->isSampler(samplerName);
706}
707
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500708void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000709{
Jamie Madill901b3792016-05-26 09:20:40 -0400710 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500711 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000712}
713
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500714void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000715{
Jamie Madill901b3792016-05-26 09:20:40 -0400716 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500717 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000718}
719
Jamie Madilldedd7b92014-11-05 16:30:36 -0500720void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000721{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500722 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000723
Jamie Madilldedd7b92014-11-05 16:30:36 -0500724 if (handle == 0)
725 {
726 texture = mZeroTextures[target].get();
727 }
728 else
729 {
Jamie Madill901b3792016-05-26 09:20:40 -0400730 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500731 }
732
733 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500734 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000735}
736
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500737void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000738{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500739 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
740 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000741}
742
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500743void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000744{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500745 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
746 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000747}
748
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500749void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000750{
Jamie Madill901b3792016-05-26 09:20:40 -0400751 Renderbuffer *renderbuffer =
752 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500753 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000754}
755
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500756void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400757{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500758 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
759 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400760}
761
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500762void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400763{
Geoff Lang76b10c92014-09-05 16:28:14 -0400764 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400765 Sampler *sampler =
766 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500767 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400768}
769
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500770void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000771{
Jamie Madill901b3792016-05-26 09:20:40 -0400772 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500773 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000774}
775
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500776void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
777 GLuint index,
778 GLintptr offset,
779 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000780{
Jamie Madill901b3792016-05-26 09:20:40 -0400781 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500782 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000783}
784
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500785void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000786{
Jamie Madill901b3792016-05-26 09:20:40 -0400787 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500788 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000789}
790
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500791void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
792 GLuint index,
793 GLintptr offset,
794 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000795{
Jamie Madill901b3792016-05-26 09:20:40 -0400796 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000798}
799
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500800void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000801{
Jamie Madill901b3792016-05-26 09:20:40 -0400802 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000804}
805
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500806void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000807{
Jamie Madill901b3792016-05-26 09:20:40 -0400808 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500809 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000810}
811
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500812void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000813{
Jamie Madill901b3792016-05-26 09:20:40 -0400814 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500815 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000816}
817
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500818void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000819{
Jamie Madill901b3792016-05-26 09:20:40 -0400820 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500821 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000822}
823
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000824void Context::useProgram(GLuint program)
825{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500826 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000827}
828
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500829void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500830{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500831 TransformFeedback *transformFeedback =
832 checkTransformFeedbackAllocation(transformFeedbackHandle);
833 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500834}
835
Geoff Lang5aad9672014-09-08 11:10:42 -0400836Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000838 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400839 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840
Geoff Lang5aad9672014-09-08 11:10:42 -0400841 // begin query
842 Error error = queryObject->begin();
843 if (error.isError())
844 {
845 return error;
846 }
847
848 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400849 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850
Geoff Lang5aad9672014-09-08 11:10:42 -0400851 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852}
853
Geoff Lang5aad9672014-09-08 11:10:42 -0400854Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855{
Shannon Woods53a94a82014-06-24 15:20:36 -0400856 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400857 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000858
Geoff Lang5aad9672014-09-08 11:10:42 -0400859 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000860
Geoff Lang5aad9672014-09-08 11:10:42 -0400861 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400862 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400863
864 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000865}
866
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500867Error Context::queryCounter(GLuint id, GLenum target)
868{
869 ASSERT(target == GL_TIMESTAMP_EXT);
870
871 Query *queryObject = getQuery(id, true, target);
872 ASSERT(queryObject);
873
874 return queryObject->queryCounter();
875}
876
877void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
878{
879 switch (pname)
880 {
881 case GL_CURRENT_QUERY_EXT:
882 params[0] = getState().getActiveQueryId(target);
883 break;
884 case GL_QUERY_COUNTER_BITS_EXT:
885 switch (target)
886 {
887 case GL_TIME_ELAPSED_EXT:
888 params[0] = getExtensions().queryCounterBitsTimeElapsed;
889 break;
890 case GL_TIMESTAMP_EXT:
891 params[0] = getExtensions().queryCounterBitsTimestamp;
892 break;
893 default:
894 UNREACHABLE();
895 params[0] = 0;
896 break;
897 }
898 break;
899 default:
900 UNREACHABLE();
901 return;
902 }
903}
904
905Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
906{
907 return GetQueryObjectParameter(this, id, pname, params);
908}
909
910Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
911{
912 return GetQueryObjectParameter(this, id, pname, params);
913}
914
915Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
916{
917 return GetQueryObjectParameter(this, id, pname, params);
918}
919
920Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
921{
922 return GetQueryObjectParameter(this, id, pname, params);
923}
924
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500925Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500927 auto framebufferIt = mFramebufferMap.find(handle);
928 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929}
930
Jamie Madill33dc8432013-07-26 11:55:05 -0400931FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000932{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500933 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000934
Jamie Madill33dc8432013-07-26 11:55:05 -0400935 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000936 {
937 return NULL;
938 }
939 else
940 {
941 return fence->second;
942 }
943}
944
945Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
946{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500947 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948
949 if (query == mQueryMap.end())
950 {
951 return NULL;
952 }
953 else
954 {
955 if (!query->second && create)
956 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400957 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958 query->second->addRef();
959 }
960 return query->second;
961 }
962}
963
Geoff Lang70d0f492015-12-10 17:45:46 -0500964Query *Context::getQuery(GLuint handle) const
965{
966 auto iter = mQueryMap.find(handle);
967 return (iter != mQueryMap.end()) ? iter->second : nullptr;
968}
969
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500970Texture *Context::getTargetTexture(GLenum target) const
971{
Ian Ewellbda75592016-04-18 17:25:54 -0400972 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500973 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000974}
975
Geoff Lang76b10c92014-09-05 16:28:14 -0400976Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500978 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000979}
980
Geoff Lang492a7e42014-11-05 13:27:06 -0500981Compiler *Context::getCompiler() const
982{
983 return mCompiler;
984}
985
Jamie Madill893ab082014-05-16 16:56:10 -0400986void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987{
988 switch (pname)
989 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000990 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000991 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400993 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400994 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996}
997
Jamie Madill893ab082014-05-16 16:56:10 -0400998void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999{
Shannon Woods53a94a82014-06-24 15:20:36 -04001000 // Queries about context capabilities and maximums are answered by Context.
1001 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002 switch (pname)
1003 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001005 params[0] = mCaps.minAliasedLineWidth;
1006 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007 break;
1008 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001009 params[0] = mCaps.minAliasedPointSize;
1010 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001012 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001013 ASSERT(mExtensions.textureFilterAnisotropic);
1014 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001015 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001016 case GL_MAX_TEXTURE_LOD_BIAS:
1017 *params = mCaps.maxLODBias;
1018 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001020 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001021 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023}
1024
Jamie Madill893ab082014-05-16 16:56:10 -04001025void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026{
Shannon Woods53a94a82014-06-24 15:20:36 -04001027 // Queries about context capabilities and maximums are answered by Context.
1028 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001029
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030 switch (pname)
1031 {
Geoff Lang301d1612014-07-09 10:34:37 -04001032 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1033 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1034 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001035 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1036 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1037 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001038 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1039 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1040 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001041 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001042 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1043 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1044 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001045 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001046 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001047 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1048 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1049 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1050 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001051 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1052 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001053 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1054 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001055 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001056 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1057 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1058 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1059 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001060 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1061 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001062 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1063 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001064 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1065 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1066 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001067 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1068 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1069 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001070 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071 case GL_MAX_VIEWPORT_DIMS:
1072 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001073 params[0] = mCaps.maxViewportWidth;
1074 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001075 }
1076 break;
1077 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001078 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1081 *params = mResetStrategy;
1082 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001083 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001084 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001086 case GL_SHADER_BINARY_FORMATS:
1087 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1088 break;
1089 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001090 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001091 break;
1092 case GL_PROGRAM_BINARY_FORMATS:
1093 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001094 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001095 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001096 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001097 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001098
1099 // GL_KHR_debug
1100 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1101 *params = mExtensions.maxDebugMessageLength;
1102 break;
1103 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1104 *params = mExtensions.maxDebugLoggedMessages;
1105 break;
1106 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1107 *params = mExtensions.maxDebugGroupStackDepth;
1108 break;
1109 case GL_MAX_LABEL_LENGTH:
1110 *params = mExtensions.maxLabelLength;
1111 break;
1112
Ian Ewell53f59f42016-01-28 17:36:55 -05001113 // GL_EXT_disjoint_timer_query
1114 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001115 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001116 break;
1117
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001118 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001119 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001120 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001121 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001122}
1123
Jamie Madill893ab082014-05-16 16:56:10 -04001124void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001125{
Shannon Woods53a94a82014-06-24 15:20:36 -04001126 // Queries about context capabilities and maximums are answered by Context.
1127 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001128 switch (pname)
1129 {
1130 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001131 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001132 break;
1133 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001134 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 break;
1136 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001137 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001138 break;
1139 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001140 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001141 break;
1142 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001143 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001144 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001145
1146 // GL_EXT_disjoint_timer_query
1147 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001148 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001149 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001150 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001151 UNREACHABLE();
1152 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001153 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001154}
1155
Geoff Lang70d0f492015-12-10 17:45:46 -05001156void Context::getPointerv(GLenum pname, void **params) const
1157{
1158 mState.getPointerv(pname, params);
1159}
1160
Shannon Woods1b2fb852013-08-19 14:28:48 -04001161bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1162{
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 // Queries about context capabilities and maximums are answered by Context.
1164 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001165 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001166 // mere passthrough.
1167 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001168}
1169
1170bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1171{
Shannon Woods53a94a82014-06-24 15:20:36 -04001172 // Queries about context capabilities and maximums are answered by Context.
1173 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001174 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001175 // mere passthrough.
1176 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001177}
1178
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1180{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001181 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1182 {
1183 *type = GL_INT;
1184 *numParams = 1;
1185 return true;
1186 }
1187
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1189 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1190 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001191 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1193 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1194 // application.
1195 switch (pname)
1196 {
1197 case GL_COMPRESSED_TEXTURE_FORMATS:
1198 {
1199 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001200 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001201 }
1202 return true;
1203 case GL_PROGRAM_BINARY_FORMATS_OES:
1204 {
1205 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001206 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001207 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001208 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209 case GL_SHADER_BINARY_FORMATS:
1210 {
1211 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001212 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001214 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001215
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001216 case GL_MAX_VERTEX_ATTRIBS:
1217 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1218 case GL_MAX_VARYING_VECTORS:
1219 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1220 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1221 case GL_MAX_TEXTURE_IMAGE_UNITS:
1222 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1223 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001224 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001225 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001226 case GL_NUM_SHADER_BINARY_FORMATS:
1227 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1228 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001229 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1230 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1231 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 case GL_RENDERBUFFER_BINDING:
1233 case GL_CURRENT_PROGRAM:
1234 case GL_PACK_ALIGNMENT:
1235 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1236 case GL_UNPACK_ALIGNMENT:
1237 case GL_GENERATE_MIPMAP_HINT:
1238 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1239 case GL_RED_BITS:
1240 case GL_GREEN_BITS:
1241 case GL_BLUE_BITS:
1242 case GL_ALPHA_BITS:
1243 case GL_DEPTH_BITS:
1244 case GL_STENCIL_BITS:
1245 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1246 case GL_CULL_FACE_MODE:
1247 case GL_FRONT_FACE:
1248 case GL_ACTIVE_TEXTURE:
1249 case GL_STENCIL_FUNC:
1250 case GL_STENCIL_VALUE_MASK:
1251 case GL_STENCIL_REF:
1252 case GL_STENCIL_FAIL:
1253 case GL_STENCIL_PASS_DEPTH_FAIL:
1254 case GL_STENCIL_PASS_DEPTH_PASS:
1255 case GL_STENCIL_BACK_FUNC:
1256 case GL_STENCIL_BACK_VALUE_MASK:
1257 case GL_STENCIL_BACK_REF:
1258 case GL_STENCIL_BACK_FAIL:
1259 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1260 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1261 case GL_DEPTH_FUNC:
1262 case GL_BLEND_SRC_RGB:
1263 case GL_BLEND_SRC_ALPHA:
1264 case GL_BLEND_DST_RGB:
1265 case GL_BLEND_DST_ALPHA:
1266 case GL_BLEND_EQUATION_RGB:
1267 case GL_BLEND_EQUATION_ALPHA:
1268 case GL_STENCIL_WRITEMASK:
1269 case GL_STENCIL_BACK_WRITEMASK:
1270 case GL_STENCIL_CLEAR_VALUE:
1271 case GL_SUBPIXEL_BITS:
1272 case GL_MAX_TEXTURE_SIZE:
1273 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1274 case GL_SAMPLE_BUFFERS:
1275 case GL_SAMPLES:
1276 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1277 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1278 case GL_TEXTURE_BINDING_2D:
1279 case GL_TEXTURE_BINDING_CUBE_MAP:
1280 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1281 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 {
1283 *type = GL_INT;
1284 *numParams = 1;
1285 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001286 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287 case GL_MAX_SAMPLES_ANGLE:
1288 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001289 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001290 {
1291 *type = GL_INT;
1292 *numParams = 1;
1293 }
1294 else
1295 {
1296 return false;
1297 }
1298 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001299 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 case GL_MAX_VIEWPORT_DIMS:
1301 {
1302 *type = GL_INT;
1303 *numParams = 2;
1304 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001305 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001306 case GL_VIEWPORT:
1307 case GL_SCISSOR_BOX:
1308 {
1309 *type = GL_INT;
1310 *numParams = 4;
1311 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001312 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313 case GL_SHADER_COMPILER:
1314 case GL_SAMPLE_COVERAGE_INVERT:
1315 case GL_DEPTH_WRITEMASK:
1316 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1317 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1318 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1319 case GL_SAMPLE_COVERAGE:
1320 case GL_SCISSOR_TEST:
1321 case GL_STENCIL_TEST:
1322 case GL_DEPTH_TEST:
1323 case GL_BLEND:
1324 case GL_DITHER:
1325 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1326 {
1327 *type = GL_BOOL;
1328 *numParams = 1;
1329 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001330 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001331 case GL_COLOR_WRITEMASK:
1332 {
1333 *type = GL_BOOL;
1334 *numParams = 4;
1335 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001336 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337 case GL_POLYGON_OFFSET_FACTOR:
1338 case GL_POLYGON_OFFSET_UNITS:
1339 case GL_SAMPLE_COVERAGE_VALUE:
1340 case GL_DEPTH_CLEAR_VALUE:
1341 case GL_LINE_WIDTH:
1342 {
1343 *type = GL_FLOAT;
1344 *numParams = 1;
1345 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001346 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347 case GL_ALIASED_LINE_WIDTH_RANGE:
1348 case GL_ALIASED_POINT_SIZE_RANGE:
1349 case GL_DEPTH_RANGE:
1350 {
1351 *type = GL_FLOAT;
1352 *numParams = 2;
1353 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001354 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001355 case GL_COLOR_CLEAR_VALUE:
1356 case GL_BLEND_COLOR:
1357 {
1358 *type = GL_FLOAT;
1359 *numParams = 4;
1360 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001361 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001362 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001363 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001364 {
1365 return false;
1366 }
1367 *type = GL_FLOAT;
1368 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001369 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001370 case GL_TIMESTAMP_EXT:
1371 if (!mExtensions.disjointTimerQuery)
1372 {
1373 return false;
1374 }
1375 *type = GL_INT_64_ANGLEX;
1376 *numParams = 1;
1377 return true;
1378 case GL_GPU_DISJOINT_EXT:
1379 if (!mExtensions.disjointTimerQuery)
1380 {
1381 return false;
1382 }
1383 *type = GL_INT;
1384 *numParams = 1;
1385 return true;
Sami Väisänena797e062016-05-12 15:23:40 +03001386 case GL_COVERAGE_MODULATION_CHROMIUM:
1387 if (!mExtensions.framebufferMixedSamples)
1388 {
1389 return false;
1390 }
1391 *type = GL_INT;
1392 *numParams = 1;
1393 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001394 }
1395
Geoff Lang70d0f492015-12-10 17:45:46 -05001396 if (mExtensions.debug)
1397 {
1398 switch (pname)
1399 {
1400 case GL_DEBUG_LOGGED_MESSAGES:
1401 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1402 case GL_DEBUG_GROUP_STACK_DEPTH:
1403 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1404 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1405 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1406 case GL_MAX_LABEL_LENGTH:
1407 *type = GL_INT;
1408 *numParams = 1;
1409 return true;
1410
1411 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1412 case GL_DEBUG_OUTPUT:
1413 *type = GL_BOOL;
1414 *numParams = 1;
1415 return true;
1416 }
1417 }
1418
Sami Väisänen74c23472016-05-09 17:30:30 +03001419 if (mExtensions.multisampleCompatibility)
1420 {
1421 switch (pname)
1422 {
1423 case GL_MULTISAMPLE_EXT:
1424 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1425 *type = GL_BOOL;
1426 *numParams = 1;
1427 return true;
1428 }
1429 }
1430
Austin Kinrossbc781f32015-10-26 09:27:38 -07001431 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1432 switch (pname)
1433 {
1434 case GL_PACK_ROW_LENGTH:
1435 case GL_PACK_SKIP_ROWS:
1436 case GL_PACK_SKIP_PIXELS:
1437 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1438 {
1439 return false;
1440 }
1441 *type = GL_INT;
1442 *numParams = 1;
1443 return true;
1444 case GL_UNPACK_ROW_LENGTH:
1445 case GL_UNPACK_SKIP_ROWS:
1446 case GL_UNPACK_SKIP_PIXELS:
1447 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1448 {
1449 return false;
1450 }
1451 *type = GL_INT;
1452 *numParams = 1;
1453 return true;
1454 case GL_VERTEX_ARRAY_BINDING:
1455 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1456 {
1457 return false;
1458 }
1459 *type = GL_INT;
1460 *numParams = 1;
1461 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001462 case GL_PIXEL_PACK_BUFFER_BINDING:
1463 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1464 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1465 {
1466 return false;
1467 }
1468 *type = GL_INT;
1469 *numParams = 1;
1470 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001471 }
1472
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001473 if (mClientVersion < 3)
1474 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001475 return false;
1476 }
1477
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001478 // Check for ES3.0+ parameter names
1479 switch (pname)
1480 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001481 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1482 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001483 case GL_UNIFORM_BUFFER_BINDING:
1484 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001485 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001486 case GL_COPY_READ_BUFFER_BINDING:
1487 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001488 case GL_SAMPLER_BINDING:
1489 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001490 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001491 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001492 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001493 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001494 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1495 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1496 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001497 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1498 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001499 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001500 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1501 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001502 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1503 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001504 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001505 case GL_MAJOR_VERSION:
1506 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001507 case GL_MAX_ELEMENTS_INDICES:
1508 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001509 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001510 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001511 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001512 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001513 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001514 {
1515 *type = GL_INT;
1516 *numParams = 1;
1517 }
1518 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519
1520 case GL_MAX_ELEMENT_INDEX:
1521 case GL_MAX_UNIFORM_BLOCK_SIZE:
1522 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1523 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1524 case GL_MAX_SERVER_WAIT_TIMEOUT:
1525 {
1526 *type = GL_INT_64_ANGLEX;
1527 *numParams = 1;
1528 }
1529 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001530
1531 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001532 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001533 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001534 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001535 {
1536 *type = GL_BOOL;
1537 *numParams = 1;
1538 }
1539 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001540
1541 case GL_MAX_TEXTURE_LOD_BIAS:
1542 {
1543 *type = GL_FLOAT;
1544 *numParams = 1;
1545 }
1546 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001547 }
1548
1549 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001550}
1551
Shannon Woods1b2fb852013-08-19 14:28:48 -04001552bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1553{
1554 if (mClientVersion < 3)
1555 {
1556 return false;
1557 }
1558
1559 switch (target)
1560 {
1561 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1562 case GL_UNIFORM_BUFFER_BINDING:
1563 {
1564 *type = GL_INT;
1565 *numParams = 1;
1566 }
1567 return true;
1568 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1569 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1570 case GL_UNIFORM_BUFFER_START:
1571 case GL_UNIFORM_BUFFER_SIZE:
1572 {
1573 *type = GL_INT_64_ANGLEX;
1574 *numParams = 1;
1575 }
1576 }
1577
1578 return false;
1579}
1580
Geoff Langf6db0982015-08-25 13:04:00 -04001581Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001582{
Jamie Madill1b94d432015-08-07 13:23:23 -04001583 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001584 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Geoff Langf6db0982015-08-25 13:04:00 -04001585 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001586
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001587 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001588}
1589
Geoff Langf6db0982015-08-25 13:04:00 -04001590Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1591{
1592 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001593 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Geoff Langf6db0982015-08-25 13:04:00 -04001594 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1595
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001596 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001597}
1598
1599Error Context::drawElements(GLenum mode,
1600 GLsizei count,
1601 GLenum type,
1602 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001603 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001604{
Jamie Madill1b94d432015-08-07 13:23:23 -04001605 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001606 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001607}
1608
1609Error Context::drawElementsInstanced(GLenum mode,
1610 GLsizei count,
1611 GLenum type,
1612 const GLvoid *indices,
1613 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001614 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001615{
1616 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001617 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1618 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001619}
1620
1621Error Context::drawRangeElements(GLenum mode,
1622 GLuint start,
1623 GLuint end,
1624 GLsizei count,
1625 GLenum type,
1626 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001627 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001628{
1629 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001630 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001631}
1632
Geoff Lang129753a2015-01-09 16:52:09 -05001633Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001634{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001635 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001636}
1637
1638Error Context::finish()
1639{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001640 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001641}
1642
Austin Kinross6ee1e782015-05-29 17:05:37 -07001643void Context::insertEventMarker(GLsizei length, const char *marker)
1644{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001645 ASSERT(mImplementation);
1646 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001647}
1648
1649void Context::pushGroupMarker(GLsizei length, const char *marker)
1650{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001651 ASSERT(mImplementation);
1652 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001653}
1654
1655void Context::popGroupMarker()
1656{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001657 ASSERT(mImplementation);
1658 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001659}
1660
Geoff Langd8605522016-04-13 10:19:12 -04001661void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1662{
1663 Program *programObject = getProgram(program);
1664 ASSERT(programObject);
1665
1666 programObject->bindUniformLocation(location, name);
1667}
1668
Sami Väisänena797e062016-05-12 15:23:40 +03001669void Context::setCoverageModulation(GLenum components)
1670{
1671 mState.setCoverageModulation(components);
1672}
1673
Jamie Madill437fa652016-05-03 15:13:24 -04001674void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001675{
Geoff Langda5777c2014-07-11 09:52:58 -04001676 if (error.isError())
1677 {
1678 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001679
1680 if (!error.getMessage().empty())
1681 {
1682 auto &debug = mState.getDebug();
1683 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1684 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1685 }
Geoff Langda5777c2014-07-11 09:52:58 -04001686 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687}
1688
1689// Get one of the recorded errors and clear its flag, if any.
1690// [OpenGL ES 2.0.24] section 2.5 page 13.
1691GLenum Context::getError()
1692{
Geoff Langda5777c2014-07-11 09:52:58 -04001693 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001694 {
Geoff Langda5777c2014-07-11 09:52:58 -04001695 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001696 }
Geoff Langda5777c2014-07-11 09:52:58 -04001697 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001698 {
Geoff Langda5777c2014-07-11 09:52:58 -04001699 GLenum error = *mErrors.begin();
1700 mErrors.erase(mErrors.begin());
1701 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001702 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001703}
1704
1705GLenum Context::getResetStatus()
1706{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001707 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001708 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001709 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001710 // mResetStatus will be set by the markContextLost callback
1711 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001712 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001713 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001714 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001715 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001716 }
1717
1718 GLenum status = mResetStatus;
1719
1720 if (mResetStatus != GL_NO_ERROR)
1721 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001722 ASSERT(mContextLost);
1723
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001724 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001725 {
1726 mResetStatus = GL_NO_ERROR;
1727 }
1728 }
Jamie Madill893ab082014-05-16 16:56:10 -04001729
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001730 return status;
1731}
1732
1733bool Context::isResetNotificationEnabled()
1734{
1735 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1736}
1737
Corentin Walleze3b10e82015-05-20 11:06:25 -04001738const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001739{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001740 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001741}
1742
1743EGLenum Context::getClientType() const
1744{
1745 return mClientType;
1746}
1747
1748EGLenum Context::getRenderBuffer() const
1749{
Corentin Wallez37c39792015-08-20 14:19:46 -04001750 auto framebufferIt = mFramebufferMap.find(0);
1751 if (framebufferIt != mFramebufferMap.end())
1752 {
1753 const Framebuffer *framebuffer = framebufferIt->second;
1754 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1755
1756 ASSERT(backAttachment != nullptr);
1757 return backAttachment->getSurface()->getRenderBuffer();
1758 }
1759 else
1760 {
1761 return EGL_NONE;
1762 }
Régis Fénéon83107972015-02-05 12:57:44 +01001763}
1764
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001765VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001766{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001767 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001768 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1769 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001770 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001771 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1772
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001773 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001774 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001775
1776 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001777}
1778
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001779TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001780{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001781 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001782 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1783 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001784 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001785 transformFeedback =
1786 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001787 transformFeedback->addRef();
1788 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001789 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001790
1791 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001792}
1793
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001794Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1795{
1796 // Can be called from Bind without a prior call to Gen.
1797 auto framebufferIt = mFramebufferMap.find(framebuffer);
1798 bool neverCreated = framebufferIt == mFramebufferMap.end();
1799 if (neverCreated || framebufferIt->second == nullptr)
1800 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001801 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001802 if (neverCreated)
1803 {
1804 mFramebufferHandleAllocator.reserve(framebuffer);
1805 mFramebufferMap[framebuffer] = newFBO;
1806 return newFBO;
1807 }
1808
1809 framebufferIt->second = newFBO;
1810 }
1811
1812 return framebufferIt->second;
1813}
1814
Geoff Lang36167ab2015-12-07 10:27:14 -05001815bool Context::isVertexArrayGenerated(GLuint vertexArray)
1816{
1817 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1818}
1819
1820bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1821{
1822 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1823}
1824
Shannon Woods53a94a82014-06-24 15:20:36 -04001825void Context::detachTexture(GLuint texture)
1826{
1827 // Simple pass-through to State's detachTexture method, as textures do not require
1828 // allocation map management either here or in the resource manager at detach time.
1829 // Zero textures are held by the Context, and we don't attempt to request them from
1830 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001831 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001832}
1833
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834void Context::detachBuffer(GLuint buffer)
1835{
Yuly Novikov5807a532015-12-03 13:01:22 -05001836 // Simple pass-through to State's detachBuffer method, since
1837 // only buffer attachments to container objects that are bound to the current context
1838 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001839
Yuly Novikov5807a532015-12-03 13:01:22 -05001840 // [OpenGL ES 3.2] section 5.1.2 page 45:
1841 // Attachments to unbound container objects, such as
1842 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1843 // are not affected and continue to act as references on the deleted object
1844 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001845}
1846
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847void Context::detachFramebuffer(GLuint framebuffer)
1848{
Shannon Woods53a94a82014-06-24 15:20:36 -04001849 // Framebuffer detachment is handled by Context, because 0 is a valid
1850 // Framebuffer object, and a pointer to it must be passed from Context
1851 // to State at binding time.
1852
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001853 // [OpenGL ES 2.0.24] section 4.4 page 107:
1854 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1855 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1856
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001857 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001858 {
1859 bindReadFramebuffer(0);
1860 }
1861
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001862 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001863 {
1864 bindDrawFramebuffer(0);
1865 }
1866}
1867
1868void Context::detachRenderbuffer(GLuint renderbuffer)
1869{
Shannon Woods53a94a82014-06-24 15:20:36 -04001870 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001871}
1872
Jamie Madill57a89722013-07-02 11:57:03 -04001873void Context::detachVertexArray(GLuint vertexArray)
1874{
Jamie Madill77a72f62015-04-14 11:18:32 -04001875 // Vertex array detachment is handled by Context, because 0 is a valid
1876 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001877 // binding time.
1878
Jamie Madill57a89722013-07-02 11:57:03 -04001879 // [OpenGL ES 3.0.2] section 2.10 page 43:
1880 // If a vertex array object that is currently bound is deleted, the binding
1881 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001882 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001883 {
1884 bindVertexArray(0);
1885 }
1886}
1887
Geoff Langc8058452014-02-03 12:04:11 -05001888void Context::detachTransformFeedback(GLuint transformFeedback)
1889{
Corentin Walleza2257da2016-04-19 16:43:12 -04001890 // Transform feedback detachment is handled by Context, because 0 is a valid
1891 // transform feedback, and a pointer to it must be passed from Context to State at
1892 // binding time.
1893
1894 // The OpenGL specification doesn't mention what should happen when the currently bound
1895 // transform feedback object is deleted. Since it is a container object, we treat it like
1896 // VAOs and FBOs and set the current bound transform feedback back to 0.
1897 if (mState.removeTransformFeedbackBinding(transformFeedback))
1898 {
1899 bindTransformFeedback(0);
1900 }
Geoff Langc8058452014-02-03 12:04:11 -05001901}
1902
Jamie Madilldc356042013-07-19 16:36:57 -04001903void Context::detachSampler(GLuint sampler)
1904{
Shannon Woods53a94a82014-06-24 15:20:36 -04001905 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001906}
1907
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001908void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1909{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001910 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001911}
1912
Jamie Madille29d1672013-07-19 16:36:57 -04001913void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1914{
Jamie Madill901b3792016-05-26 09:20:40 -04001915 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001916
1917 Sampler *samplerObject = getSampler(sampler);
1918 ASSERT(samplerObject);
1919
Geoff Lang69cce582015-09-17 13:20:36 -04001920 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001921 switch (pname)
1922 {
Geoff Lang69cce582015-09-17 13:20:36 -04001923 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1924 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1925 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1926 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1927 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1928 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1929 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1930 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1931 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1932 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1933 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001934 }
Geoff Lang69cce582015-09-17 13:20:36 -04001935 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001936}
1937
1938void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1939{
Jamie Madill901b3792016-05-26 09:20:40 -04001940 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001941
1942 Sampler *samplerObject = getSampler(sampler);
1943 ASSERT(samplerObject);
1944
Geoff Lang69cce582015-09-17 13:20:36 -04001945 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001946 switch (pname)
1947 {
Geoff Lang69cce582015-09-17 13:20:36 -04001948 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1949 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1950 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1951 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1952 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1953 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1954 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1955 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1956 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1957 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1958 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001959 }
Geoff Lang69cce582015-09-17 13:20:36 -04001960 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001961}
1962
Jamie Madill9675b802013-07-19 16:36:59 -04001963GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1964{
Jamie Madill901b3792016-05-26 09:20:40 -04001965 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001966
1967 Sampler *samplerObject = getSampler(sampler);
1968 ASSERT(samplerObject);
1969
Geoff Lang69cce582015-09-17 13:20:36 -04001970 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001971 switch (pname)
1972 {
Geoff Lang69cce582015-09-17 13:20:36 -04001973 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1974 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1975 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1976 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1977 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1978 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001979 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1980 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001981 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1982 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1983 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001984 }
Geoff Lang69cce582015-09-17 13:20:36 -04001985 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001986}
1987
1988GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1989{
Jamie Madill901b3792016-05-26 09:20:40 -04001990 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001991
1992 Sampler *samplerObject = getSampler(sampler);
1993 ASSERT(samplerObject);
1994
Geoff Lang69cce582015-09-17 13:20:36 -04001995 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001996 switch (pname)
1997 {
Geoff Lang69cce582015-09-17 13:20:36 -04001998 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1999 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2000 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2001 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2002 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2003 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2004 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2005 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2006 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2007 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2008 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002009 }
Geoff Lang69cce582015-09-17 13:20:36 -04002010 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002011}
2012
Olli Etuahof0fee072016-03-30 15:11:58 +03002013void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2014{
2015 gl::Program *programObject = getProgram(program);
2016 ASSERT(programObject != nullptr);
2017
2018 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2019 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2020}
2021
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002022void Context::initRendererString()
2023{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002024 std::ostringstream rendererString;
2025 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002026 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002027 rendererString << ")";
2028
Geoff Langcec35902014-04-16 10:52:36 -04002029 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002030}
2031
Geoff Langc0b9ef42014-07-02 10:02:37 -04002032const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002033{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002034 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002035}
2036
Geoff Langcec35902014-04-16 10:52:36 -04002037void Context::initExtensionStrings()
2038{
Geoff Lang493daf52014-07-03 13:38:44 -04002039 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002040
Geoff Langc0b9ef42014-07-02 10:02:37 -04002041 std::ostringstream combinedStringStream;
2042 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2043 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002044}
2045
Geoff Langc0b9ef42014-07-02 10:02:37 -04002046const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002047{
2048 return mExtensionString;
2049}
2050
Geoff Langc0b9ef42014-07-02 10:02:37 -04002051const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002052{
2053 return mExtensionStrings[idx];
2054}
2055
2056size_t Context::getExtensionStringCount() const
2057{
2058 return mExtensionStrings.size();
2059}
2060
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002061void Context::beginTransformFeedback(GLenum primitiveMode)
2062{
2063 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2064 ASSERT(transformFeedback != nullptr);
2065 ASSERT(!transformFeedback->isPaused());
2066
2067 transformFeedback->begin(primitiveMode, getState().getProgram());
2068}
2069
2070bool Context::hasActiveTransformFeedback(GLuint program) const
2071{
2072 for (auto pair : mTransformFeedbackMap)
2073 {
2074 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2075 {
2076 return true;
2077 }
2078 }
2079 return false;
2080}
2081
Jamie Madill00ed7a12016-05-19 13:13:38 -04002082void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002083{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002084 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002085
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002086 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002087
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002088 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002089
Jamie Madill00ed7a12016-05-19 13:13:38 -04002090 if (mClientVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002091 {
2092 // Disable ES3+ extensions
2093 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002094 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002095 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002096 }
2097
Jamie Madill00ed7a12016-05-19 13:13:38 -04002098 if (mClientVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002099 {
2100 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2101 //mExtensions.sRGB = false;
2102 }
2103
Jamie Madill00ed7a12016-05-19 13:13:38 -04002104 // Some extensions are always available because they are implemented in the GL layer.
2105 mExtensions.bindUniformLocation = true;
2106 mExtensions.vertexArrayObject = true;
2107
2108 // Enable the no error extension if the context was created with the flag.
2109 mExtensions.noError = mSkipValidation;
2110
Geoff Lang70d0f492015-12-10 17:45:46 -05002111 // Explicitly enable GL_KHR_debug
2112 mExtensions.debug = true;
2113 mExtensions.maxDebugMessageLength = 1024;
2114 mExtensions.maxDebugLoggedMessages = 1024;
2115 mExtensions.maxDebugGroupStackDepth = 1024;
2116 mExtensions.maxLabelLength = 1024;
2117
Geoff Lang301d1612014-07-09 10:34:37 -04002118 // Apply implementation limits
2119 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002120 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2121 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2122
2123 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002124
Geoff Lang900013c2014-07-07 11:32:19 -04002125 mCaps.compressedTextureFormats.clear();
2126
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002127 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002128 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2129 {
2130 GLenum format = i->first;
2131 TextureCaps formatCaps = i->second;
2132
Geoff Lang5d601382014-07-22 15:14:06 -04002133 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002134
Geoff Lang0d8b7242015-09-09 14:56:53 -04002135 // Update the format caps based on the client version and extensions.
2136 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2137 // ES3.
2138 formatCaps.texturable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002139 formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002140 formatCaps.renderable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002141 formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002142 formatCaps.filterable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002143 formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002144
2145 // OpenGL ES does not support multisampling with integer formats
2146 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002147 {
Geoff Langd87878e2014-09-19 15:42:59 -04002148 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002149 }
Geoff Langd87878e2014-09-19 15:42:59 -04002150
2151 if (formatCaps.texturable && formatInfo.compressed)
2152 {
2153 mCaps.compressedTextureFormats.push_back(format);
2154 }
2155
2156 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002157 }
2158}
2159
Jamie Madill1b94d432015-08-07 13:23:23 -04002160void Context::syncRendererState()
2161{
2162 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002163 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002164 mState.clearDirtyBits();
2165 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002166}
2167
Jamie Madillad9f24e2016-02-12 09:27:24 -05002168void Context::syncRendererState(const State::DirtyBits &bitMask,
2169 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002170{
2171 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002172 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002173 mState.clearDirtyBits(dirtyBits);
2174
Jamie Madillad9f24e2016-02-12 09:27:24 -05002175 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002176}
Jamie Madillc29968b2016-01-20 11:17:23 -05002177
2178void Context::blitFramebuffer(GLint srcX0,
2179 GLint srcY0,
2180 GLint srcX1,
2181 GLint srcY1,
2182 GLint dstX0,
2183 GLint dstY0,
2184 GLint dstX1,
2185 GLint dstY1,
2186 GLbitfield mask,
2187 GLenum filter)
2188{
Jamie Madillc29968b2016-01-20 11:17:23 -05002189 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2190 ASSERT(drawFramebuffer);
2191
2192 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2193 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2194
Jamie Madillad9f24e2016-02-12 09:27:24 -05002195 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002196
Jamie Madill8415b5f2016-04-26 13:41:39 -04002197 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002198}
Jamie Madillc29968b2016-01-20 11:17:23 -05002199
2200void Context::clear(GLbitfield mask)
2201{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002202 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002203 handleError(mState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002204}
2205
2206void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2207{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002208 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002209 handleError(mState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2210 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002211}
2212
2213void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2214{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002215 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002216 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2217 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002218}
2219
2220void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2221{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002222 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002223 handleError(mState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2224 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002225}
2226
2227void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2228{
2229 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2230 ASSERT(framebufferObject);
2231
2232 // If a buffer is not present, the clear has no effect
2233 if (framebufferObject->getDepthbuffer() == nullptr &&
2234 framebufferObject->getStencilbuffer() == nullptr)
2235 {
2236 return;
2237 }
2238
Jamie Madillad9f24e2016-02-12 09:27:24 -05002239 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002240 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2241 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002242}
2243
2244void Context::readPixels(GLint x,
2245 GLint y,
2246 GLsizei width,
2247 GLsizei height,
2248 GLenum format,
2249 GLenum type,
2250 GLvoid *pixels)
2251{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002252 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002253
2254 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2255 ASSERT(framebufferObject);
2256
2257 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002258 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002259}
2260
2261void Context::copyTexImage2D(GLenum target,
2262 GLint level,
2263 GLenum internalformat,
2264 GLint x,
2265 GLint y,
2266 GLsizei width,
2267 GLsizei height,
2268 GLint border)
2269{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002270 // Only sync the read FBO
2271 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2272
Jamie Madillc29968b2016-01-20 11:17:23 -05002273 Rectangle sourceArea(x, y, width, height);
2274
2275 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2276 Texture *texture =
2277 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002278 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002279}
2280
2281void Context::copyTexSubImage2D(GLenum target,
2282 GLint level,
2283 GLint xoffset,
2284 GLint yoffset,
2285 GLint x,
2286 GLint y,
2287 GLsizei width,
2288 GLsizei height)
2289{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002290 // Only sync the read FBO
2291 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2292
Jamie Madillc29968b2016-01-20 11:17:23 -05002293 Offset destOffset(xoffset, yoffset, 0);
2294 Rectangle sourceArea(x, y, width, height);
2295
2296 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2297 Texture *texture =
2298 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002299 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002300}
2301
2302void Context::copyTexSubImage3D(GLenum target,
2303 GLint level,
2304 GLint xoffset,
2305 GLint yoffset,
2306 GLint zoffset,
2307 GLint x,
2308 GLint y,
2309 GLsizei width,
2310 GLsizei height)
2311{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002312 // Only sync the read FBO
2313 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2314
Jamie Madillc29968b2016-01-20 11:17:23 -05002315 Offset destOffset(xoffset, yoffset, zoffset);
2316 Rectangle sourceArea(x, y, width, height);
2317
2318 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2319 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002320 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002321}
2322
2323void Context::framebufferTexture2D(GLenum target,
2324 GLenum attachment,
2325 GLenum textarget,
2326 GLuint texture,
2327 GLint level)
2328{
2329 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2330 ASSERT(framebuffer);
2331
2332 if (texture != 0)
2333 {
2334 Texture *textureObj = getTexture(texture);
2335
2336 ImageIndex index = ImageIndex::MakeInvalid();
2337
2338 if (textarget == GL_TEXTURE_2D)
2339 {
2340 index = ImageIndex::Make2D(level);
2341 }
2342 else
2343 {
2344 ASSERT(IsCubeMapTextureTarget(textarget));
2345 index = ImageIndex::MakeCube(textarget, level);
2346 }
2347
2348 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2349 }
2350 else
2351 {
2352 framebuffer->resetAttachment(attachment);
2353 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002354
2355 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002356}
2357
2358void Context::framebufferRenderbuffer(GLenum target,
2359 GLenum attachment,
2360 GLenum renderbuffertarget,
2361 GLuint renderbuffer)
2362{
2363 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2364 ASSERT(framebuffer);
2365
2366 if (renderbuffer != 0)
2367 {
2368 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2369 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2370 renderbufferObject);
2371 }
2372 else
2373 {
2374 framebuffer->resetAttachment(attachment);
2375 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002376
2377 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002378}
2379
2380void Context::framebufferTextureLayer(GLenum target,
2381 GLenum attachment,
2382 GLuint texture,
2383 GLint level,
2384 GLint layer)
2385{
2386 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2387 ASSERT(framebuffer);
2388
2389 if (texture != 0)
2390 {
2391 Texture *textureObject = getTexture(texture);
2392
2393 ImageIndex index = ImageIndex::MakeInvalid();
2394
2395 if (textureObject->getTarget() == GL_TEXTURE_3D)
2396 {
2397 index = ImageIndex::Make3D(level, layer);
2398 }
2399 else
2400 {
2401 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2402 index = ImageIndex::Make2DArray(level, layer);
2403 }
2404
2405 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2406 }
2407 else
2408 {
2409 framebuffer->resetAttachment(attachment);
2410 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002411
2412 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002413}
2414
2415void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2416{
2417 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2418 ASSERT(framebuffer);
2419 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002420 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002421}
2422
2423void Context::readBuffer(GLenum mode)
2424{
2425 Framebuffer *readFBO = mState.getReadFramebuffer();
2426 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002427 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002428}
2429
2430void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2431{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002432 // Only sync the FBO
2433 mState.syncDirtyObject(target);
2434
Jamie Madillc29968b2016-01-20 11:17:23 -05002435 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2436 ASSERT(framebuffer);
2437
2438 // The specification isn't clear what should be done when the framebuffer isn't complete.
2439 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002440 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002441}
2442
2443void Context::invalidateFramebuffer(GLenum target,
2444 GLsizei numAttachments,
2445 const GLenum *attachments)
2446{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002447 // Only sync the FBO
2448 mState.syncDirtyObject(target);
2449
Jamie Madillc29968b2016-01-20 11:17:23 -05002450 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2451 ASSERT(framebuffer);
2452
Jamie Madill437fa652016-05-03 15:13:24 -04002453 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002454 {
Jamie Madill437fa652016-05-03 15:13:24 -04002455 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 }
Jamie Madill437fa652016-05-03 15:13:24 -04002457
2458 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002459}
2460
2461void Context::invalidateSubFramebuffer(GLenum target,
2462 GLsizei numAttachments,
2463 const GLenum *attachments,
2464 GLint x,
2465 GLint y,
2466 GLsizei width,
2467 GLsizei height)
2468{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002469 // Only sync the FBO
2470 mState.syncDirtyObject(target);
2471
Jamie Madillc29968b2016-01-20 11:17:23 -05002472 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2473 ASSERT(framebuffer);
2474
Jamie Madill437fa652016-05-03 15:13:24 -04002475 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 {
Jamie Madill437fa652016-05-03 15:13:24 -04002477 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002478 }
Jamie Madill437fa652016-05-03 15:13:24 -04002479
2480 Rectangle area(x, y, width, height);
2481 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002482}
2483
Jamie Madill73a84962016-02-12 09:27:23 -05002484void Context::texImage2D(GLenum target,
2485 GLint level,
2486 GLint internalformat,
2487 GLsizei width,
2488 GLsizei height,
2489 GLint border,
2490 GLenum format,
2491 GLenum type,
2492 const GLvoid *pixels)
2493{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002494 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002495
2496 Extents size(width, height, 1);
2497 Texture *texture =
2498 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002499 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2500 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002501}
2502
2503void Context::texImage3D(GLenum target,
2504 GLint level,
2505 GLint internalformat,
2506 GLsizei width,
2507 GLsizei height,
2508 GLsizei depth,
2509 GLint border,
2510 GLenum format,
2511 GLenum type,
2512 const GLvoid *pixels)
2513{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002514 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002515
2516 Extents size(width, height, depth);
2517 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002518 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2519 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002520}
2521
2522void Context::texSubImage2D(GLenum target,
2523 GLint level,
2524 GLint xoffset,
2525 GLint yoffset,
2526 GLsizei width,
2527 GLsizei height,
2528 GLenum format,
2529 GLenum type,
2530 const GLvoid *pixels)
2531{
2532 // Zero sized uploads are valid but no-ops
2533 if (width == 0 || height == 0)
2534 {
2535 return;
2536 }
2537
Jamie Madillad9f24e2016-02-12 09:27:24 -05002538 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002539
2540 Box area(xoffset, yoffset, 0, width, height, 1);
2541 Texture *texture =
2542 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002543 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2544 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002545}
2546
2547void Context::texSubImage3D(GLenum target,
2548 GLint level,
2549 GLint xoffset,
2550 GLint yoffset,
2551 GLint zoffset,
2552 GLsizei width,
2553 GLsizei height,
2554 GLsizei depth,
2555 GLenum format,
2556 GLenum type,
2557 const GLvoid *pixels)
2558{
2559 // Zero sized uploads are valid but no-ops
2560 if (width == 0 || height == 0 || depth == 0)
2561 {
2562 return;
2563 }
2564
Jamie Madillad9f24e2016-02-12 09:27:24 -05002565 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002566
2567 Box area(xoffset, yoffset, zoffset, width, height, depth);
2568 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002569 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2570 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002571}
2572
2573void Context::compressedTexImage2D(GLenum target,
2574 GLint level,
2575 GLenum internalformat,
2576 GLsizei width,
2577 GLsizei height,
2578 GLint border,
2579 GLsizei imageSize,
2580 const GLvoid *data)
2581{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002583
2584 Extents size(width, height, 1);
2585 Texture *texture =
2586 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002587 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2588 size, imageSize,
2589 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002590}
2591
2592void Context::compressedTexImage3D(GLenum target,
2593 GLint level,
2594 GLenum internalformat,
2595 GLsizei width,
2596 GLsizei height,
2597 GLsizei depth,
2598 GLint border,
2599 GLsizei imageSize,
2600 const GLvoid *data)
2601{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002602 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002603
2604 Extents size(width, height, depth);
2605 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002606 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2607 size, imageSize,
2608 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002609}
2610
2611void Context::compressedTexSubImage2D(GLenum target,
2612 GLint level,
2613 GLint xoffset,
2614 GLint yoffset,
2615 GLsizei width,
2616 GLsizei height,
2617 GLenum format,
2618 GLsizei imageSize,
2619 const GLvoid *data)
2620{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002621 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002622
2623 Box area(xoffset, yoffset, 0, width, height, 1);
2624 Texture *texture =
2625 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002626 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2627 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002628}
2629
2630void Context::compressedTexSubImage3D(GLenum target,
2631 GLint level,
2632 GLint xoffset,
2633 GLint yoffset,
2634 GLint zoffset,
2635 GLsizei width,
2636 GLsizei height,
2637 GLsizei depth,
2638 GLenum format,
2639 GLsizei imageSize,
2640 const GLvoid *data)
2641{
2642 // Zero sized uploads are valid but no-ops
2643 if (width == 0 || height == 0)
2644 {
2645 return;
2646 }
2647
Jamie Madillad9f24e2016-02-12 09:27:24 -05002648 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002649
2650 Box area(xoffset, yoffset, zoffset, width, height, depth);
2651 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002652 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2653 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002654}
2655
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002656void Context::generateMipmap(GLenum target)
2657{
2658 Texture *texture = getTargetTexture(target);
2659 handleError(texture->generateMipmap());
2660}
2661
Olli Etuaho4f667482016-03-30 15:56:35 +03002662void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2663{
2664 Buffer *buffer = getState().getTargetBuffer(target);
2665 ASSERT(buffer);
2666
2667 if (!buffer->isMapped())
2668 {
2669 *params = nullptr;
2670 }
2671 else
2672 {
2673 *params = buffer->getMapPointer();
2674 }
2675}
2676
2677GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2678{
2679 Buffer *buffer = getState().getTargetBuffer(target);
2680 ASSERT(buffer);
2681
2682 Error error = buffer->map(access);
2683 if (error.isError())
2684 {
Jamie Madill437fa652016-05-03 15:13:24 -04002685 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002686 return nullptr;
2687 }
2688
2689 return buffer->getMapPointer();
2690}
2691
2692GLboolean Context::unmapBuffer(GLenum target)
2693{
2694 Buffer *buffer = getState().getTargetBuffer(target);
2695 ASSERT(buffer);
2696
2697 GLboolean result;
2698 Error error = buffer->unmap(&result);
2699 if (error.isError())
2700 {
Jamie Madill437fa652016-05-03 15:13:24 -04002701 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002702 return GL_FALSE;
2703 }
2704
2705 return result;
2706}
2707
2708GLvoid *Context::mapBufferRange(GLenum target,
2709 GLintptr offset,
2710 GLsizeiptr length,
2711 GLbitfield access)
2712{
2713 Buffer *buffer = getState().getTargetBuffer(target);
2714 ASSERT(buffer);
2715
2716 Error error = buffer->mapRange(offset, length, access);
2717 if (error.isError())
2718 {
Jamie Madill437fa652016-05-03 15:13:24 -04002719 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002720 return nullptr;
2721 }
2722
2723 return buffer->getMapPointer();
2724}
2725
2726void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2727{
2728 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2729}
2730
Jamie Madillad9f24e2016-02-12 09:27:24 -05002731void Context::syncStateForReadPixels()
2732{
2733 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2734}
2735
2736void Context::syncStateForTexImage()
2737{
2738 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2739}
2740
2741void Context::syncStateForClear()
2742{
2743 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2744}
2745
2746void Context::syncStateForBlit()
2747{
2748 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2749}
2750
Jamie Madillc20ab272016-06-09 07:20:46 -07002751void Context::activeTexture(GLenum texture)
2752{
2753 mState.setActiveSampler(texture - GL_TEXTURE0);
2754}
2755
2756void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2757{
2758 mState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
2759}
2760
2761void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2762{
2763 mState.setBlendEquation(modeRGB, modeAlpha);
2764}
2765
2766void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2767{
2768 mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
2769}
2770
2771void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2772{
2773 mState.setColorClearValue(red, green, blue, alpha);
2774}
2775
2776void Context::clearDepthf(GLclampf depth)
2777{
2778 mState.setDepthClearValue(depth);
2779}
2780
2781void Context::clearStencil(GLint s)
2782{
2783 mState.setStencilClearValue(s);
2784}
2785
2786void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2787{
2788 mState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
2789}
2790
2791void Context::cullFace(GLenum mode)
2792{
2793 mState.setCullMode(mode);
2794}
2795
2796void Context::depthFunc(GLenum func)
2797{
2798 mState.setDepthFunc(func);
2799}
2800
2801void Context::depthMask(GLboolean flag)
2802{
2803 mState.setDepthMask(flag != GL_FALSE);
2804}
2805
2806void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2807{
2808 mState.setDepthRange(zNear, zFar);
2809}
2810
2811void Context::disable(GLenum cap)
2812{
2813 mState.setEnableFeature(cap, false);
2814}
2815
2816void Context::disableVertexAttribArray(GLuint index)
2817{
2818 mState.setEnableVertexAttribArray(index, false);
2819}
2820
2821void Context::enable(GLenum cap)
2822{
2823 mState.setEnableFeature(cap, true);
2824}
2825
2826void Context::enableVertexAttribArray(GLuint index)
2827{
2828 mState.setEnableVertexAttribArray(index, true);
2829}
2830
2831void Context::frontFace(GLenum mode)
2832{
2833 mState.setFrontFace(mode);
2834}
2835
2836void Context::hint(GLenum target, GLenum mode)
2837{
2838 switch (target)
2839 {
2840 case GL_GENERATE_MIPMAP_HINT:
2841 mState.setGenerateMipmapHint(mode);
2842 break;
2843
2844 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2845 mState.setFragmentShaderDerivativeHint(mode);
2846 break;
2847
2848 default:
2849 UNREACHABLE();
2850 return;
2851 }
2852}
2853
2854void Context::lineWidth(GLfloat width)
2855{
2856 mState.setLineWidth(width);
2857}
2858
2859void Context::pixelStorei(GLenum pname, GLint param)
2860{
2861 switch (pname)
2862 {
2863 case GL_UNPACK_ALIGNMENT:
2864 mState.setUnpackAlignment(param);
2865 break;
2866
2867 case GL_PACK_ALIGNMENT:
2868 mState.setPackAlignment(param);
2869 break;
2870
2871 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2872 mState.setPackReverseRowOrder(param != 0);
2873 break;
2874
2875 case GL_UNPACK_ROW_LENGTH:
2876 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
2877 mState.setUnpackRowLength(param);
2878 break;
2879
2880 case GL_UNPACK_IMAGE_HEIGHT:
2881 ASSERT(getClientVersion() >= 3);
2882 mState.setUnpackImageHeight(param);
2883 break;
2884
2885 case GL_UNPACK_SKIP_IMAGES:
2886 ASSERT(getClientVersion() >= 3);
2887 mState.setUnpackSkipImages(param);
2888 break;
2889
2890 case GL_UNPACK_SKIP_ROWS:
2891 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
2892 mState.setUnpackSkipRows(param);
2893 break;
2894
2895 case GL_UNPACK_SKIP_PIXELS:
2896 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
2897 mState.setUnpackSkipPixels(param);
2898 break;
2899
2900 case GL_PACK_ROW_LENGTH:
2901 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
2902 mState.setPackRowLength(param);
2903 break;
2904
2905 case GL_PACK_SKIP_ROWS:
2906 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
2907 mState.setPackSkipRows(param);
2908 break;
2909
2910 case GL_PACK_SKIP_PIXELS:
2911 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
2912 mState.setPackSkipPixels(param);
2913 break;
2914
2915 default:
2916 UNREACHABLE();
2917 return;
2918 }
2919}
2920
2921void Context::polygonOffset(GLfloat factor, GLfloat units)
2922{
2923 mState.setPolygonOffsetParams(factor, units);
2924}
2925
2926void Context::sampleCoverage(GLclampf value, GLboolean invert)
2927{
2928 mState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
2929}
2930
2931void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2932{
2933 mState.setScissorParams(x, y, width, height);
2934}
2935
2936void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2937{
2938 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2939 {
2940 mState.setStencilParams(func, ref, mask);
2941 }
2942
2943 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2944 {
2945 mState.setStencilBackParams(func, ref, mask);
2946 }
2947}
2948
2949void Context::stencilMaskSeparate(GLenum face, GLuint mask)
2950{
2951 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2952 {
2953 mState.setStencilWritemask(mask);
2954 }
2955
2956 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2957 {
2958 mState.setStencilBackWritemask(mask);
2959 }
2960}
2961
2962void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
2963{
2964 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2965 {
2966 mState.setStencilOperations(fail, zfail, zpass);
2967 }
2968
2969 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2970 {
2971 mState.setStencilBackOperations(fail, zfail, zpass);
2972 }
2973}
2974
2975void Context::vertexAttrib1f(GLuint index, GLfloat x)
2976{
2977 GLfloat vals[4] = {x, 0, 0, 1};
2978 mState.setVertexAttribf(index, vals);
2979}
2980
2981void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
2982{
2983 GLfloat vals[4] = {values[0], 0, 0, 1};
2984 mState.setVertexAttribf(index, vals);
2985}
2986
2987void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
2988{
2989 GLfloat vals[4] = {x, y, 0, 1};
2990 mState.setVertexAttribf(index, vals);
2991}
2992
2993void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
2994{
2995 GLfloat vals[4] = {values[0], values[1], 0, 1};
2996 mState.setVertexAttribf(index, vals);
2997}
2998
2999void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3000{
3001 GLfloat vals[4] = {x, y, z, 1};
3002 mState.setVertexAttribf(index, vals);
3003}
3004
3005void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3006{
3007 GLfloat vals[4] = {values[0], values[1], values[2], 1};
3008 mState.setVertexAttribf(index, vals);
3009}
3010
3011void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3012{
3013 GLfloat vals[4] = {x, y, z, w};
3014 mState.setVertexAttribf(index, vals);
3015}
3016
3017void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3018{
3019 mState.setVertexAttribf(index, values);
3020}
3021
3022void Context::vertexAttribPointer(GLuint index,
3023 GLint size,
3024 GLenum type,
3025 GLboolean normalized,
3026 GLsizei stride,
3027 const GLvoid *ptr)
3028{
3029 mState.setVertexAttribState(index, mState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3030 normalized == GL_TRUE, false, stride, ptr);
3031}
3032
3033void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3034{
3035 mState.setViewportParams(x, y, width, height);
3036}
3037
3038void Context::vertexAttribIPointer(GLuint index,
3039 GLint size,
3040 GLenum type,
3041 GLsizei stride,
3042 const GLvoid *pointer)
3043{
3044 mState.setVertexAttribState(index, mState.getTargetBuffer(GL_ARRAY_BUFFER), size, type, false,
3045 true, stride, pointer);
3046}
3047
3048void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3049{
3050 GLint vals[4] = {x, y, z, w};
3051 mState.setVertexAttribi(index, vals);
3052}
3053
3054void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3055{
3056 GLuint vals[4] = {x, y, z, w};
3057 mState.setVertexAttribu(index, vals);
3058}
3059
3060void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3061{
3062 mState.setVertexAttribi(index, v);
3063}
3064
3065void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3066{
3067 mState.setVertexAttribu(index, v);
3068}
3069
3070void Context::debugMessageControl(GLenum source,
3071 GLenum type,
3072 GLenum severity,
3073 GLsizei count,
3074 const GLuint *ids,
3075 GLboolean enabled)
3076{
3077 std::vector<GLuint> idVector(ids, ids + count);
3078 mState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3079 (enabled != GL_FALSE));
3080}
3081
3082void Context::debugMessageInsert(GLenum source,
3083 GLenum type,
3084 GLuint id,
3085 GLenum severity,
3086 GLsizei length,
3087 const GLchar *buf)
3088{
3089 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
3090 mState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
3091}
3092
3093void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3094{
3095 mState.getDebug().setCallback(callback, userParam);
3096}
3097
3098GLuint Context::getDebugMessageLog(GLuint count,
3099 GLsizei bufSize,
3100 GLenum *sources,
3101 GLenum *types,
3102 GLuint *ids,
3103 GLenum *severities,
3104 GLsizei *lengths,
3105 GLchar *messageLog)
3106{
3107 return static_cast<GLuint>(mState.getDebug().getMessages(count, bufSize, sources, types, ids,
3108 severities, lengths, messageLog));
3109}
3110
3111void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3112{
3113 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
3114 mState.getDebug().pushGroup(source, id, std::move(msg));
3115}
3116
3117void Context::popDebugGroup()
3118{
3119 mState.getDebug().popGroup();
3120}
3121
Jamie Madillc29968b2016-01-20 11:17:23 -05003122} // namespace gl