blob: 16ce6997578fb0f5cf95b3c98bf1deb24d173799 [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 Madill46e6c7a2016-01-18 14:42:30 -0500152 initCaps(mClientVersion);
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 Madill53ea9cc2016-05-17 10:12:52 -0400165 mResourceManager = new ResourceManager(mImplementation.get());
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{
414 return mResourceManager->createProgram();
415}
416
417GLuint Context::createShader(GLenum type)
418{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 return mResourceManager->createShader(mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
422GLuint Context::createTexture()
423{
424 return mResourceManager->createTexture();
425}
426
427GLuint Context::createRenderbuffer()
428{
429 return mResourceManager->createRenderbuffer();
430}
431
Geoff Lang882033e2014-09-30 11:26:07 -0400432GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400433{
434 GLuint handle = mResourceManager->createFenceSync();
435
Cooper Partind8e62a32015-01-29 15:21:25 -0800436 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400437}
438
Jamie Madill57a89722013-07-02 11:57:03 -0400439GLuint Context::createVertexArray()
440{
Geoff Lang36167ab2015-12-07 10:27:14 -0500441 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
442 mVertexArrayMap[vertexArray] = nullptr;
443 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400444}
445
Jamie Madilldc356042013-07-19 16:36:57 -0400446GLuint Context::createSampler()
447{
448 return mResourceManager->createSampler();
449}
450
Geoff Langc8058452014-02-03 12:04:11 -0500451GLuint Context::createTransformFeedback()
452{
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
454 mTransformFeedbackMap[transformFeedback] = nullptr;
455 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500456}
457
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458// Returns an unused framebuffer name
459GLuint Context::createFramebuffer()
460{
461 GLuint handle = mFramebufferHandleAllocator.allocate();
462
463 mFramebufferMap[handle] = NULL;
464
465 return handle;
466}
467
Jamie Madill33dc8432013-07-26 11:55:05 -0400468GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469{
Jamie Madill33dc8432013-07-26 11:55:05 -0400470 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400472 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473
474 return handle;
475}
476
477// Returns an unused query name
478GLuint Context::createQuery()
479{
480 GLuint handle = mQueryHandleAllocator.allocate();
481
482 mQueryMap[handle] = NULL;
483
484 return handle;
485}
486
487void Context::deleteBuffer(GLuint buffer)
488{
489 if (mResourceManager->getBuffer(buffer))
490 {
491 detachBuffer(buffer);
492 }
Jamie Madill893ab082014-05-16 16:56:10 -0400493
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494 mResourceManager->deleteBuffer(buffer);
495}
496
497void Context::deleteShader(GLuint shader)
498{
499 mResourceManager->deleteShader(shader);
500}
501
502void Context::deleteProgram(GLuint program)
503{
504 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000505}
506
507void Context::deleteTexture(GLuint texture)
508{
509 if (mResourceManager->getTexture(texture))
510 {
511 detachTexture(texture);
512 }
513
514 mResourceManager->deleteTexture(texture);
515}
516
517void Context::deleteRenderbuffer(GLuint renderbuffer)
518{
519 if (mResourceManager->getRenderbuffer(renderbuffer))
520 {
521 detachRenderbuffer(renderbuffer);
522 }
Jamie Madill893ab082014-05-16 16:56:10 -0400523
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524 mResourceManager->deleteRenderbuffer(renderbuffer);
525}
526
Jamie Madillcd055f82013-07-26 11:55:15 -0400527void Context::deleteFenceSync(GLsync fenceSync)
528{
529 // The spec specifies the underlying Fence object is not deleted until all current
530 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
531 // and since our API is currently designed for being called from a single thread, we can delete
532 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700533 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400534}
535
Jamie Madill57a89722013-07-02 11:57:03 -0400536void Context::deleteVertexArray(GLuint vertexArray)
537{
Geoff Lang36167ab2015-12-07 10:27:14 -0500538 auto iter = mVertexArrayMap.find(vertexArray);
539 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000540 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500541 VertexArray *vertexArrayObject = iter->second;
542 if (vertexArrayObject != nullptr)
543 {
544 detachVertexArray(vertexArray);
545 delete vertexArrayObject;
546 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000547
Geoff Lang36167ab2015-12-07 10:27:14 -0500548 mVertexArrayMap.erase(iter);
549 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400550 }
551}
552
Jamie Madilldc356042013-07-19 16:36:57 -0400553void Context::deleteSampler(GLuint sampler)
554{
555 if (mResourceManager->getSampler(sampler))
556 {
557 detachSampler(sampler);
558 }
559
560 mResourceManager->deleteSampler(sampler);
561}
562
Geoff Langc8058452014-02-03 12:04:11 -0500563void Context::deleteTransformFeedback(GLuint transformFeedback)
564{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500565 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500566 if (iter != mTransformFeedbackMap.end())
567 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 TransformFeedback *transformFeedbackObject = iter->second;
569 if (transformFeedbackObject != nullptr)
570 {
571 detachTransformFeedback(transformFeedback);
572 transformFeedbackObject->release();
573 }
574
Geoff Lang50b3fe82015-12-08 14:49:12 +0000575 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500576 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500577 }
578}
579
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580void Context::deleteFramebuffer(GLuint framebuffer)
581{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500582 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583
584 if (framebufferObject != mFramebufferMap.end())
585 {
586 detachFramebuffer(framebuffer);
587
588 mFramebufferHandleAllocator.release(framebufferObject->first);
589 delete framebufferObject->second;
590 mFramebufferMap.erase(framebufferObject);
591 }
592}
593
Jamie Madill33dc8432013-07-26 11:55:05 -0400594void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500596 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597
Jamie Madill33dc8432013-07-26 11:55:05 -0400598 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400600 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000601 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400602 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603 }
604}
605
606void Context::deleteQuery(GLuint query)
607{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500608 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609 if (queryObject != mQueryMap.end())
610 {
611 mQueryHandleAllocator.release(queryObject->first);
612 if (queryObject->second)
613 {
614 queryObject->second->release();
615 }
616 mQueryMap.erase(queryObject);
617 }
618}
619
Geoff Lang70d0f492015-12-10 17:45:46 -0500620Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621{
622 return mResourceManager->getBuffer(handle);
623}
624
Geoff Lang48dcae72014-02-05 16:28:24 -0500625Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626{
627 return mResourceManager->getShader(handle);
628}
629
Geoff Lang48dcae72014-02-05 16:28:24 -0500630Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631{
632 return mResourceManager->getProgram(handle);
633}
634
Jamie Madill570f7c82014-07-03 10:38:54 -0400635Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636{
637 return mResourceManager->getTexture(handle);
638}
639
Geoff Lang70d0f492015-12-10 17:45:46 -0500640Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641{
642 return mResourceManager->getRenderbuffer(handle);
643}
644
Jamie Madillcd055f82013-07-26 11:55:15 -0400645FenceSync *Context::getFenceSync(GLsync handle) const
646{
Minmin Gong794e0002015-04-07 18:31:54 -0700647 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400648}
649
Jamie Madill57a89722013-07-02 11:57:03 -0400650VertexArray *Context::getVertexArray(GLuint handle) const
651{
652 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500653 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400654}
655
Jamie Madilldc356042013-07-19 16:36:57 -0400656Sampler *Context::getSampler(GLuint handle) const
657{
658 return mResourceManager->getSampler(handle);
659}
660
Geoff Langc8058452014-02-03 12:04:11 -0500661TransformFeedback *Context::getTransformFeedback(GLuint handle) const
662{
Geoff Lang36167ab2015-12-07 10:27:14 -0500663 auto iter = mTransformFeedbackMap.find(handle);
664 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500665}
666
Geoff Lang70d0f492015-12-10 17:45:46 -0500667LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
668{
669 switch (identifier)
670 {
671 case GL_BUFFER:
672 return getBuffer(name);
673 case GL_SHADER:
674 return getShader(name);
675 case GL_PROGRAM:
676 return getProgram(name);
677 case GL_VERTEX_ARRAY:
678 return getVertexArray(name);
679 case GL_QUERY:
680 return getQuery(name);
681 case GL_TRANSFORM_FEEDBACK:
682 return getTransformFeedback(name);
683 case GL_SAMPLER:
684 return getSampler(name);
685 case GL_TEXTURE:
686 return getTexture(name);
687 case GL_RENDERBUFFER:
688 return getRenderbuffer(name);
689 case GL_FRAMEBUFFER:
690 return getFramebuffer(name);
691 default:
692 UNREACHABLE();
693 return nullptr;
694 }
695}
696
697LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
698{
699 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
700}
701
Jamie Madilldc356042013-07-19 16:36:57 -0400702bool Context::isSampler(GLuint samplerName) const
703{
704 return mResourceManager->isSampler(samplerName);
705}
706
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500707void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
710 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000711}
712
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500713void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500715 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
716 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000717}
718
Jamie Madilldedd7b92014-11-05 16:30:36 -0500719void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000720{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500721 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000722
Jamie Madilldedd7b92014-11-05 16:30:36 -0500723 if (handle == 0)
724 {
725 texture = mZeroTextures[target].get();
726 }
727 else
728 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500729 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500730 }
731
732 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500733 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000734}
735
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500736void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000737{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500738 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
739 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740}
741
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500742void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000743{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500744 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
745 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000746}
747
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500748void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000749{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500750 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
751 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000752}
753
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500754void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400755{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500756 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
757 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400758}
759
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500760void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400761{
Geoff Lang76b10c92014-09-05 16:28:14 -0400762 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500763 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
764 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400765}
766
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500767void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000768{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500769 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
770 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000771}
772
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500773void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
774 GLuint index,
775 GLintptr offset,
776 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000777{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500778 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
779 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000780}
781
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500782void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000783{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500784 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
785 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000786}
787
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500788void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
789 GLuint index,
790 GLintptr offset,
791 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000792{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500793 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
794 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000795}
796
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000798{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
800 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000801}
802
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000804{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500805 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
806 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000807}
808
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500809void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000810{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500811 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
812 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000813}
814
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500815void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000816{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500817 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
818 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000819}
820
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821void Context::useProgram(GLuint program)
822{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500823 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000824}
825
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500826void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500827{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500828 TransformFeedback *transformFeedback =
829 checkTransformFeedbackAllocation(transformFeedbackHandle);
830 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500831}
832
Geoff Lang5aad9672014-09-08 11:10:42 -0400833Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400836 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837
Geoff Lang5aad9672014-09-08 11:10:42 -0400838 // begin query
839 Error error = queryObject->begin();
840 if (error.isError())
841 {
842 return error;
843 }
844
845 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400846 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847
Geoff Lang5aad9672014-09-08 11:10:42 -0400848 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849}
850
Geoff Lang5aad9672014-09-08 11:10:42 -0400851Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852{
Shannon Woods53a94a82014-06-24 15:20:36 -0400853 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400854 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855
Geoff Lang5aad9672014-09-08 11:10:42 -0400856 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857
Geoff Lang5aad9672014-09-08 11:10:42 -0400858 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400859 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400860
861 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862}
863
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500864Error Context::queryCounter(GLuint id, GLenum target)
865{
866 ASSERT(target == GL_TIMESTAMP_EXT);
867
868 Query *queryObject = getQuery(id, true, target);
869 ASSERT(queryObject);
870
871 return queryObject->queryCounter();
872}
873
874void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
875{
876 switch (pname)
877 {
878 case GL_CURRENT_QUERY_EXT:
879 params[0] = getState().getActiveQueryId(target);
880 break;
881 case GL_QUERY_COUNTER_BITS_EXT:
882 switch (target)
883 {
884 case GL_TIME_ELAPSED_EXT:
885 params[0] = getExtensions().queryCounterBitsTimeElapsed;
886 break;
887 case GL_TIMESTAMP_EXT:
888 params[0] = getExtensions().queryCounterBitsTimestamp;
889 break;
890 default:
891 UNREACHABLE();
892 params[0] = 0;
893 break;
894 }
895 break;
896 default:
897 UNREACHABLE();
898 return;
899 }
900}
901
902Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
903{
904 return GetQueryObjectParameter(this, id, pname, params);
905}
906
907Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
908{
909 return GetQueryObjectParameter(this, id, pname, params);
910}
911
912Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
913{
914 return GetQueryObjectParameter(this, id, pname, params);
915}
916
917Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
918{
919 return GetQueryObjectParameter(this, id, pname, params);
920}
921
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500922Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500924 auto framebufferIt = mFramebufferMap.find(handle);
925 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madill33dc8432013-07-26 11:55:05 -0400928FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500930 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madill33dc8432013-07-26 11:55:05 -0400932 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933 {
934 return NULL;
935 }
936 else
937 {
938 return fence->second;
939 }
940}
941
942Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
943{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500944 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945
946 if (query == mQueryMap.end())
947 {
948 return NULL;
949 }
950 else
951 {
952 if (!query->second && create)
953 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400954 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955 query->second->addRef();
956 }
957 return query->second;
958 }
959}
960
Geoff Lang70d0f492015-12-10 17:45:46 -0500961Query *Context::getQuery(GLuint handle) const
962{
963 auto iter = mQueryMap.find(handle);
964 return (iter != mQueryMap.end()) ? iter->second : nullptr;
965}
966
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500967Texture *Context::getTargetTexture(GLenum target) const
968{
Ian Ewellbda75592016-04-18 17:25:54 -0400969 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500970 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000971}
972
Geoff Lang76b10c92014-09-05 16:28:14 -0400973Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976}
977
Geoff Lang492a7e42014-11-05 13:27:06 -0500978Compiler *Context::getCompiler() const
979{
980 return mCompiler;
981}
982
Jamie Madill893ab082014-05-16 16:56:10 -0400983void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
985 switch (pname)
986 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000987 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000988 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400990 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400991 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill893ab082014-05-16 16:56:10 -0400995void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996{
Shannon Woods53a94a82014-06-24 15:20:36 -0400997 // Queries about context capabilities and maximums are answered by Context.
998 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999 switch (pname)
1000 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 params[0] = mCaps.minAliasedLineWidth;
1003 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 break;
1005 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001006 params[0] = mCaps.minAliasedPointSize;
1007 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001009 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001010 ASSERT(mExtensions.textureFilterAnisotropic);
1011 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001012 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001013 case GL_MAX_TEXTURE_LOD_BIAS:
1014 *params = mCaps.maxLODBias;
1015 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001017 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001018 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020}
1021
Jamie Madill893ab082014-05-16 16:56:10 -04001022void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023{
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 // Queries about context capabilities and maximums are answered by Context.
1025 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001026
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001027 switch (pname)
1028 {
Geoff Lang301d1612014-07-09 10:34:37 -04001029 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1030 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1031 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001032 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1033 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1034 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001035 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1036 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1037 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001038 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001039 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1040 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1041 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001042 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001043 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001044 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1045 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1046 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1047 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001048 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1049 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001050 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1051 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001052 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001053 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1054 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1055 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1056 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001057 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1058 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001059 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1060 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001061 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1062 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1063 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001064 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1065 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1066 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001067 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 case GL_MAX_VIEWPORT_DIMS:
1069 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001070 params[0] = mCaps.maxViewportWidth;
1071 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072 }
1073 break;
1074 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001075 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1078 *params = mResetStrategy;
1079 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001080 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001081 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001083 case GL_SHADER_BINARY_FORMATS:
1084 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1085 break;
1086 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001087 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001088 break;
1089 case GL_PROGRAM_BINARY_FORMATS:
1090 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001092 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001093 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001094 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001095
1096 // GL_KHR_debug
1097 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1098 *params = mExtensions.maxDebugMessageLength;
1099 break;
1100 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1101 *params = mExtensions.maxDebugLoggedMessages;
1102 break;
1103 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1104 *params = mExtensions.maxDebugGroupStackDepth;
1105 break;
1106 case GL_MAX_LABEL_LENGTH:
1107 *params = mExtensions.maxLabelLength;
1108 break;
1109
Ian Ewell53f59f42016-01-28 17:36:55 -05001110 // GL_EXT_disjoint_timer_query
1111 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001112 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001113 break;
1114
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001116 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001117 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001118 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001119}
1120
Jamie Madill893ab082014-05-16 16:56:10 -04001121void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001122{
Shannon Woods53a94a82014-06-24 15:20:36 -04001123 // Queries about context capabilities and maximums are answered by Context.
1124 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001125 switch (pname)
1126 {
1127 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001128 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001129 break;
1130 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001131 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001132 break;
1133 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001134 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 break;
1136 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001137 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001138 break;
1139 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001140 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001141 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001142
1143 // GL_EXT_disjoint_timer_query
1144 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001145 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001146 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001147 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001148 UNREACHABLE();
1149 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001150 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001151}
1152
Geoff Lang70d0f492015-12-10 17:45:46 -05001153void Context::getPointerv(GLenum pname, void **params) const
1154{
1155 mState.getPointerv(pname, params);
1156}
1157
Shannon Woods1b2fb852013-08-19 14:28:48 -04001158bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1159{
Shannon Woods53a94a82014-06-24 15:20:36 -04001160 // Queries about context capabilities and maximums are answered by Context.
1161 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001162 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 // mere passthrough.
1164 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001165}
1166
1167bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1168{
Shannon Woods53a94a82014-06-24 15:20:36 -04001169 // Queries about context capabilities and maximums are answered by Context.
1170 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001171 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001172 // mere passthrough.
1173 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001174}
1175
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1177{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001178 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1179 {
1180 *type = GL_INT;
1181 *numParams = 1;
1182 return true;
1183 }
1184
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1186 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1187 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001188 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1190 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1191 // application.
1192 switch (pname)
1193 {
1194 case GL_COMPRESSED_TEXTURE_FORMATS:
1195 {
1196 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001197 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001198 }
1199 return true;
1200 case GL_PROGRAM_BINARY_FORMATS_OES:
1201 {
1202 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001203 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001205 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 case GL_SHADER_BINARY_FORMATS:
1207 {
1208 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001209 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001211 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213 case GL_MAX_VERTEX_ATTRIBS:
1214 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1215 case GL_MAX_VARYING_VECTORS:
1216 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1217 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1218 case GL_MAX_TEXTURE_IMAGE_UNITS:
1219 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1220 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001221 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001222 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 case GL_NUM_SHADER_BINARY_FORMATS:
1224 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1225 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001226 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1227 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1228 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 case GL_RENDERBUFFER_BINDING:
1230 case GL_CURRENT_PROGRAM:
1231 case GL_PACK_ALIGNMENT:
1232 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1233 case GL_UNPACK_ALIGNMENT:
1234 case GL_GENERATE_MIPMAP_HINT:
1235 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1236 case GL_RED_BITS:
1237 case GL_GREEN_BITS:
1238 case GL_BLUE_BITS:
1239 case GL_ALPHA_BITS:
1240 case GL_DEPTH_BITS:
1241 case GL_STENCIL_BITS:
1242 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1243 case GL_CULL_FACE_MODE:
1244 case GL_FRONT_FACE:
1245 case GL_ACTIVE_TEXTURE:
1246 case GL_STENCIL_FUNC:
1247 case GL_STENCIL_VALUE_MASK:
1248 case GL_STENCIL_REF:
1249 case GL_STENCIL_FAIL:
1250 case GL_STENCIL_PASS_DEPTH_FAIL:
1251 case GL_STENCIL_PASS_DEPTH_PASS:
1252 case GL_STENCIL_BACK_FUNC:
1253 case GL_STENCIL_BACK_VALUE_MASK:
1254 case GL_STENCIL_BACK_REF:
1255 case GL_STENCIL_BACK_FAIL:
1256 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1257 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1258 case GL_DEPTH_FUNC:
1259 case GL_BLEND_SRC_RGB:
1260 case GL_BLEND_SRC_ALPHA:
1261 case GL_BLEND_DST_RGB:
1262 case GL_BLEND_DST_ALPHA:
1263 case GL_BLEND_EQUATION_RGB:
1264 case GL_BLEND_EQUATION_ALPHA:
1265 case GL_STENCIL_WRITEMASK:
1266 case GL_STENCIL_BACK_WRITEMASK:
1267 case GL_STENCIL_CLEAR_VALUE:
1268 case GL_SUBPIXEL_BITS:
1269 case GL_MAX_TEXTURE_SIZE:
1270 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1271 case GL_SAMPLE_BUFFERS:
1272 case GL_SAMPLES:
1273 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1274 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1275 case GL_TEXTURE_BINDING_2D:
1276 case GL_TEXTURE_BINDING_CUBE_MAP:
1277 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1278 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 {
1280 *type = GL_INT;
1281 *numParams = 1;
1282 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001283 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 case GL_MAX_SAMPLES_ANGLE:
1285 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001286 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287 {
1288 *type = GL_INT;
1289 *numParams = 1;
1290 }
1291 else
1292 {
1293 return false;
1294 }
1295 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001296 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297 case GL_MAX_VIEWPORT_DIMS:
1298 {
1299 *type = GL_INT;
1300 *numParams = 2;
1301 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001302 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001303 case GL_VIEWPORT:
1304 case GL_SCISSOR_BOX:
1305 {
1306 *type = GL_INT;
1307 *numParams = 4;
1308 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001309 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310 case GL_SHADER_COMPILER:
1311 case GL_SAMPLE_COVERAGE_INVERT:
1312 case GL_DEPTH_WRITEMASK:
1313 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1314 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1315 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1316 case GL_SAMPLE_COVERAGE:
1317 case GL_SCISSOR_TEST:
1318 case GL_STENCIL_TEST:
1319 case GL_DEPTH_TEST:
1320 case GL_BLEND:
1321 case GL_DITHER:
1322 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1323 {
1324 *type = GL_BOOL;
1325 *numParams = 1;
1326 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001327 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_COLOR_WRITEMASK:
1329 {
1330 *type = GL_BOOL;
1331 *numParams = 4;
1332 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001333 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 case GL_POLYGON_OFFSET_FACTOR:
1335 case GL_POLYGON_OFFSET_UNITS:
1336 case GL_SAMPLE_COVERAGE_VALUE:
1337 case GL_DEPTH_CLEAR_VALUE:
1338 case GL_LINE_WIDTH:
1339 {
1340 *type = GL_FLOAT;
1341 *numParams = 1;
1342 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001343 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001344 case GL_ALIASED_LINE_WIDTH_RANGE:
1345 case GL_ALIASED_POINT_SIZE_RANGE:
1346 case GL_DEPTH_RANGE:
1347 {
1348 *type = GL_FLOAT;
1349 *numParams = 2;
1350 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001351 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352 case GL_COLOR_CLEAR_VALUE:
1353 case GL_BLEND_COLOR:
1354 {
1355 *type = GL_FLOAT;
1356 *numParams = 4;
1357 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001358 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001359 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001360 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001361 {
1362 return false;
1363 }
1364 *type = GL_FLOAT;
1365 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001366 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001367 case GL_TIMESTAMP_EXT:
1368 if (!mExtensions.disjointTimerQuery)
1369 {
1370 return false;
1371 }
1372 *type = GL_INT_64_ANGLEX;
1373 *numParams = 1;
1374 return true;
1375 case GL_GPU_DISJOINT_EXT:
1376 if (!mExtensions.disjointTimerQuery)
1377 {
1378 return false;
1379 }
1380 *type = GL_INT;
1381 *numParams = 1;
1382 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001383 }
1384
Geoff Lang70d0f492015-12-10 17:45:46 -05001385 if (mExtensions.debug)
1386 {
1387 switch (pname)
1388 {
1389 case GL_DEBUG_LOGGED_MESSAGES:
1390 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1391 case GL_DEBUG_GROUP_STACK_DEPTH:
1392 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1393 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1394 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1395 case GL_MAX_LABEL_LENGTH:
1396 *type = GL_INT;
1397 *numParams = 1;
1398 return true;
1399
1400 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1401 case GL_DEBUG_OUTPUT:
1402 *type = GL_BOOL;
1403 *numParams = 1;
1404 return true;
1405 }
1406 }
1407
Sami Väisänen74c23472016-05-09 17:30:30 +03001408 if (mExtensions.multisampleCompatibility)
1409 {
1410 switch (pname)
1411 {
1412 case GL_MULTISAMPLE_EXT:
1413 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1414 *type = GL_BOOL;
1415 *numParams = 1;
1416 return true;
1417 }
1418 }
1419
Austin Kinrossbc781f32015-10-26 09:27:38 -07001420 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1421 switch (pname)
1422 {
1423 case GL_PACK_ROW_LENGTH:
1424 case GL_PACK_SKIP_ROWS:
1425 case GL_PACK_SKIP_PIXELS:
1426 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1427 {
1428 return false;
1429 }
1430 *type = GL_INT;
1431 *numParams = 1;
1432 return true;
1433 case GL_UNPACK_ROW_LENGTH:
1434 case GL_UNPACK_SKIP_ROWS:
1435 case GL_UNPACK_SKIP_PIXELS:
1436 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1437 {
1438 return false;
1439 }
1440 *type = GL_INT;
1441 *numParams = 1;
1442 return true;
1443 case GL_VERTEX_ARRAY_BINDING:
1444 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1445 {
1446 return false;
1447 }
1448 *type = GL_INT;
1449 *numParams = 1;
1450 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001451 case GL_PIXEL_PACK_BUFFER_BINDING:
1452 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1453 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1454 {
1455 return false;
1456 }
1457 *type = GL_INT;
1458 *numParams = 1;
1459 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001460 }
1461
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001462 if (mClientVersion < 3)
1463 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001464 return false;
1465 }
1466
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001467 // Check for ES3.0+ parameter names
1468 switch (pname)
1469 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001470 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1471 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001472 case GL_UNIFORM_BUFFER_BINDING:
1473 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001474 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001475 case GL_COPY_READ_BUFFER_BINDING:
1476 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001477 case GL_SAMPLER_BINDING:
1478 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001479 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001480 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001481 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001482 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001483 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1484 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1485 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001486 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1487 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001488 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001489 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1490 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001491 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1492 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001493 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001494 case GL_MAJOR_VERSION:
1495 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001496 case GL_MAX_ELEMENTS_INDICES:
1497 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001498 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001499 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001500 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001501 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001502 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001503 {
1504 *type = GL_INT;
1505 *numParams = 1;
1506 }
1507 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508
1509 case GL_MAX_ELEMENT_INDEX:
1510 case GL_MAX_UNIFORM_BLOCK_SIZE:
1511 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1512 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1513 case GL_MAX_SERVER_WAIT_TIMEOUT:
1514 {
1515 *type = GL_INT_64_ANGLEX;
1516 *numParams = 1;
1517 }
1518 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001519
1520 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001521 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001522 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001523 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001524 {
1525 *type = GL_BOOL;
1526 *numParams = 1;
1527 }
1528 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001529
1530 case GL_MAX_TEXTURE_LOD_BIAS:
1531 {
1532 *type = GL_FLOAT;
1533 *numParams = 1;
1534 }
1535 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001536 }
1537
1538 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001539}
1540
Shannon Woods1b2fb852013-08-19 14:28:48 -04001541bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1542{
1543 if (mClientVersion < 3)
1544 {
1545 return false;
1546 }
1547
1548 switch (target)
1549 {
1550 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1551 case GL_UNIFORM_BUFFER_BINDING:
1552 {
1553 *type = GL_INT;
1554 *numParams = 1;
1555 }
1556 return true;
1557 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1558 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1559 case GL_UNIFORM_BUFFER_START:
1560 case GL_UNIFORM_BUFFER_SIZE:
1561 {
1562 *type = GL_INT_64_ANGLEX;
1563 *numParams = 1;
1564 }
1565 }
1566
1567 return false;
1568}
1569
Geoff Langf6db0982015-08-25 13:04:00 -04001570Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001571{
Jamie Madill1b94d432015-08-07 13:23:23 -04001572 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001573 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Geoff Langf6db0982015-08-25 13:04:00 -04001574 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001575
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001576 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001577}
1578
Geoff Langf6db0982015-08-25 13:04:00 -04001579Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1580{
1581 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001582 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Geoff Langf6db0982015-08-25 13:04:00 -04001583 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1584
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001585 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001586}
1587
1588Error Context::drawElements(GLenum mode,
1589 GLsizei count,
1590 GLenum type,
1591 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001592 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001593{
Jamie Madill1b94d432015-08-07 13:23:23 -04001594 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001595 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001596}
1597
1598Error Context::drawElementsInstanced(GLenum mode,
1599 GLsizei count,
1600 GLenum type,
1601 const GLvoid *indices,
1602 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001603 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001604{
1605 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001606 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1607 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001608}
1609
1610Error Context::drawRangeElements(GLenum mode,
1611 GLuint start,
1612 GLuint end,
1613 GLsizei count,
1614 GLenum type,
1615 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001616 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001617{
1618 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001619 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001620}
1621
Geoff Lang129753a2015-01-09 16:52:09 -05001622Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001623{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001624 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001625}
1626
1627Error Context::finish()
1628{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001629 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630}
1631
Austin Kinross6ee1e782015-05-29 17:05:37 -07001632void Context::insertEventMarker(GLsizei length, const char *marker)
1633{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001634 ASSERT(mImplementation);
1635 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001636}
1637
1638void Context::pushGroupMarker(GLsizei length, const char *marker)
1639{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001640 ASSERT(mImplementation);
1641 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001642}
1643
1644void Context::popGroupMarker()
1645{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001646 ASSERT(mImplementation);
1647 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001648}
1649
Geoff Langd8605522016-04-13 10:19:12 -04001650void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1651{
1652 Program *programObject = getProgram(program);
1653 ASSERT(programObject);
1654
1655 programObject->bindUniformLocation(location, name);
1656}
1657
Jamie Madill437fa652016-05-03 15:13:24 -04001658void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Geoff Langda5777c2014-07-11 09:52:58 -04001660 if (error.isError())
1661 {
1662 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001663
1664 if (!error.getMessage().empty())
1665 {
1666 auto &debug = mState.getDebug();
1667 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1668 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1669 }
Geoff Langda5777c2014-07-11 09:52:58 -04001670 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
1673// Get one of the recorded errors and clear its flag, if any.
1674// [OpenGL ES 2.0.24] section 2.5 page 13.
1675GLenum Context::getError()
1676{
Geoff Langda5777c2014-07-11 09:52:58 -04001677 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001678 {
Geoff Langda5777c2014-07-11 09:52:58 -04001679 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001680 }
Geoff Langda5777c2014-07-11 09:52:58 -04001681 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682 {
Geoff Langda5777c2014-07-11 09:52:58 -04001683 GLenum error = *mErrors.begin();
1684 mErrors.erase(mErrors.begin());
1685 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687}
1688
1689GLenum Context::getResetStatus()
1690{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001691 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001692 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001694 // mResetStatus will be set by the markContextLost callback
1695 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001696 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001697 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001698 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001699 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001700 }
1701
1702 GLenum status = mResetStatus;
1703
1704 if (mResetStatus != GL_NO_ERROR)
1705 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001706 ASSERT(mContextLost);
1707
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001708 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001709 {
1710 mResetStatus = GL_NO_ERROR;
1711 }
1712 }
Jamie Madill893ab082014-05-16 16:56:10 -04001713
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001714 return status;
1715}
1716
1717bool Context::isResetNotificationEnabled()
1718{
1719 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1720}
1721
Corentin Walleze3b10e82015-05-20 11:06:25 -04001722const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001723{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001724 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001725}
1726
1727EGLenum Context::getClientType() const
1728{
1729 return mClientType;
1730}
1731
1732EGLenum Context::getRenderBuffer() const
1733{
Corentin Wallez37c39792015-08-20 14:19:46 -04001734 auto framebufferIt = mFramebufferMap.find(0);
1735 if (framebufferIt != mFramebufferMap.end())
1736 {
1737 const Framebuffer *framebuffer = framebufferIt->second;
1738 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1739
1740 ASSERT(backAttachment != nullptr);
1741 return backAttachment->getSurface()->getRenderBuffer();
1742 }
1743 else
1744 {
1745 return EGL_NONE;
1746 }
Régis Fénéon83107972015-02-05 12:57:44 +01001747}
1748
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001749VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001750{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001751 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001752 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1753 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001754 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001755 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1756
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001757 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001758 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001759
1760 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001761}
1762
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001763TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001764{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001765 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001766 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1767 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001768 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001769 transformFeedback =
1770 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001771 transformFeedback->addRef();
1772 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001773 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001774
1775 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001776}
1777
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001778Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1779{
1780 // Can be called from Bind without a prior call to Gen.
1781 auto framebufferIt = mFramebufferMap.find(framebuffer);
1782 bool neverCreated = framebufferIt == mFramebufferMap.end();
1783 if (neverCreated || framebufferIt->second == nullptr)
1784 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001785 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001786 if (neverCreated)
1787 {
1788 mFramebufferHandleAllocator.reserve(framebuffer);
1789 mFramebufferMap[framebuffer] = newFBO;
1790 return newFBO;
1791 }
1792
1793 framebufferIt->second = newFBO;
1794 }
1795
1796 return framebufferIt->second;
1797}
1798
Geoff Lang36167ab2015-12-07 10:27:14 -05001799bool Context::isVertexArrayGenerated(GLuint vertexArray)
1800{
1801 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1802}
1803
1804bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1805{
1806 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1807}
1808
Shannon Woods53a94a82014-06-24 15:20:36 -04001809void Context::detachTexture(GLuint texture)
1810{
1811 // Simple pass-through to State's detachTexture method, as textures do not require
1812 // allocation map management either here or in the resource manager at detach time.
1813 // Zero textures are held by the Context, and we don't attempt to request them from
1814 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001815 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001816}
1817
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001818void Context::detachBuffer(GLuint buffer)
1819{
Yuly Novikov5807a532015-12-03 13:01:22 -05001820 // Simple pass-through to State's detachBuffer method, since
1821 // only buffer attachments to container objects that are bound to the current context
1822 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001823
Yuly Novikov5807a532015-12-03 13:01:22 -05001824 // [OpenGL ES 3.2] section 5.1.2 page 45:
1825 // Attachments to unbound container objects, such as
1826 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1827 // are not affected and continue to act as references on the deleted object
1828 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001829}
1830
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001831void Context::detachFramebuffer(GLuint framebuffer)
1832{
Shannon Woods53a94a82014-06-24 15:20:36 -04001833 // Framebuffer detachment is handled by Context, because 0 is a valid
1834 // Framebuffer object, and a pointer to it must be passed from Context
1835 // to State at binding time.
1836
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001837 // [OpenGL ES 2.0.24] section 4.4 page 107:
1838 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1839 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1840
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001841 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001842 {
1843 bindReadFramebuffer(0);
1844 }
1845
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001846 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847 {
1848 bindDrawFramebuffer(0);
1849 }
1850}
1851
1852void Context::detachRenderbuffer(GLuint renderbuffer)
1853{
Shannon Woods53a94a82014-06-24 15:20:36 -04001854 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001855}
1856
Jamie Madill57a89722013-07-02 11:57:03 -04001857void Context::detachVertexArray(GLuint vertexArray)
1858{
Jamie Madill77a72f62015-04-14 11:18:32 -04001859 // Vertex array detachment is handled by Context, because 0 is a valid
1860 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001861 // binding time.
1862
Jamie Madill57a89722013-07-02 11:57:03 -04001863 // [OpenGL ES 3.0.2] section 2.10 page 43:
1864 // If a vertex array object that is currently bound is deleted, the binding
1865 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001866 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001867 {
1868 bindVertexArray(0);
1869 }
1870}
1871
Geoff Langc8058452014-02-03 12:04:11 -05001872void Context::detachTransformFeedback(GLuint transformFeedback)
1873{
Corentin Walleza2257da2016-04-19 16:43:12 -04001874 // Transform feedback detachment is handled by Context, because 0 is a valid
1875 // transform feedback, and a pointer to it must be passed from Context to State at
1876 // binding time.
1877
1878 // The OpenGL specification doesn't mention what should happen when the currently bound
1879 // transform feedback object is deleted. Since it is a container object, we treat it like
1880 // VAOs and FBOs and set the current bound transform feedback back to 0.
1881 if (mState.removeTransformFeedbackBinding(transformFeedback))
1882 {
1883 bindTransformFeedback(0);
1884 }
Geoff Langc8058452014-02-03 12:04:11 -05001885}
1886
Jamie Madilldc356042013-07-19 16:36:57 -04001887void Context::detachSampler(GLuint sampler)
1888{
Shannon Woods53a94a82014-06-24 15:20:36 -04001889 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001890}
1891
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001892void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1893{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001894 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001895}
1896
Jamie Madille29d1672013-07-19 16:36:57 -04001897void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1898{
1899 mResourceManager->checkSamplerAllocation(sampler);
1900
1901 Sampler *samplerObject = getSampler(sampler);
1902 ASSERT(samplerObject);
1903
Geoff Lang69cce582015-09-17 13:20:36 -04001904 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001905 switch (pname)
1906 {
Geoff Lang69cce582015-09-17 13:20:36 -04001907 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1908 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1909 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1910 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1911 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1912 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1913 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1914 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1915 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1916 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1917 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001918 }
Geoff Lang69cce582015-09-17 13:20:36 -04001919 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001920}
1921
1922void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1923{
1924 mResourceManager->checkSamplerAllocation(sampler);
1925
1926 Sampler *samplerObject = getSampler(sampler);
1927 ASSERT(samplerObject);
1928
Geoff Lang69cce582015-09-17 13:20:36 -04001929 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001930 switch (pname)
1931 {
Geoff Lang69cce582015-09-17 13:20:36 -04001932 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1933 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1934 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1935 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1936 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1937 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1938 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1939 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1940 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1941 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1942 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001943 }
Geoff Lang69cce582015-09-17 13:20:36 -04001944 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001945}
1946
Jamie Madill9675b802013-07-19 16:36:59 -04001947GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1948{
1949 mResourceManager->checkSamplerAllocation(sampler);
1950
1951 Sampler *samplerObject = getSampler(sampler);
1952 ASSERT(samplerObject);
1953
Geoff Lang69cce582015-09-17 13:20:36 -04001954 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001955 switch (pname)
1956 {
Geoff Lang69cce582015-09-17 13:20:36 -04001957 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1958 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1959 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1960 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1961 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1962 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001963 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1964 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001965 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1966 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1967 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001968 }
Geoff Lang69cce582015-09-17 13:20:36 -04001969 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001970}
1971
1972GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1973{
1974 mResourceManager->checkSamplerAllocation(sampler);
1975
1976 Sampler *samplerObject = getSampler(sampler);
1977 ASSERT(samplerObject);
1978
Geoff Lang69cce582015-09-17 13:20:36 -04001979 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001980 switch (pname)
1981 {
Geoff Lang69cce582015-09-17 13:20:36 -04001982 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1983 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1984 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1985 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1986 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1987 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1988 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1989 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1990 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1991 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1992 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001993 }
Geoff Lang69cce582015-09-17 13:20:36 -04001994 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001995}
1996
Olli Etuahof0fee072016-03-30 15:11:58 +03001997void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1998{
1999 gl::Program *programObject = getProgram(program);
2000 ASSERT(programObject != nullptr);
2001
2002 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2003 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2004}
2005
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006void Context::initRendererString()
2007{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002008 std::ostringstream rendererString;
2009 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002010 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002011 rendererString << ")";
2012
Geoff Langcec35902014-04-16 10:52:36 -04002013 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002014}
2015
Geoff Langc0b9ef42014-07-02 10:02:37 -04002016const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002018 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002019}
2020
Geoff Langcec35902014-04-16 10:52:36 -04002021void Context::initExtensionStrings()
2022{
Geoff Lang493daf52014-07-03 13:38:44 -04002023 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002024
Geoff Langc0b9ef42014-07-02 10:02:37 -04002025 std::ostringstream combinedStringStream;
2026 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2027 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002028}
2029
Geoff Langc0b9ef42014-07-02 10:02:37 -04002030const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002031{
2032 return mExtensionString;
2033}
2034
Geoff Langc0b9ef42014-07-02 10:02:37 -04002035const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002036{
2037 return mExtensionStrings[idx];
2038}
2039
2040size_t Context::getExtensionStringCount() const
2041{
2042 return mExtensionStrings.size();
2043}
2044
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002045void Context::beginTransformFeedback(GLenum primitiveMode)
2046{
2047 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2048 ASSERT(transformFeedback != nullptr);
2049 ASSERT(!transformFeedback->isPaused());
2050
2051 transformFeedback->begin(primitiveMode, getState().getProgram());
2052}
2053
2054bool Context::hasActiveTransformFeedback(GLuint program) const
2055{
2056 for (auto pair : mTransformFeedbackMap)
2057 {
2058 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2059 {
2060 return true;
2061 }
2062 }
2063 return false;
2064}
2065
Geoff Lang493daf52014-07-03 13:38:44 -04002066void Context::initCaps(GLuint clientVersion)
2067{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002068 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002069
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002070 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002071
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002072 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002073
Geoff Lang493daf52014-07-03 13:38:44 -04002074 if (clientVersion < 3)
2075 {
2076 // Disable ES3+ extensions
2077 mExtensions.colorBufferFloat = false;
2078 }
2079
2080 if (clientVersion > 2)
2081 {
2082 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2083 //mExtensions.sRGB = false;
2084 }
2085
Geoff Lang70d0f492015-12-10 17:45:46 -05002086 // Explicitly enable GL_KHR_debug
2087 mExtensions.debug = true;
2088 mExtensions.maxDebugMessageLength = 1024;
2089 mExtensions.maxDebugLoggedMessages = 1024;
2090 mExtensions.maxDebugGroupStackDepth = 1024;
2091 mExtensions.maxLabelLength = 1024;
2092
Geoff Lang301d1612014-07-09 10:34:37 -04002093 // Apply implementation limits
2094 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002095 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2096 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2097
2098 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002099
Geoff Lang900013c2014-07-07 11:32:19 -04002100 mCaps.compressedTextureFormats.clear();
2101
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002102 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002103 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2104 {
2105 GLenum format = i->first;
2106 TextureCaps formatCaps = i->second;
2107
Geoff Lang5d601382014-07-22 15:14:06 -04002108 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002109
Geoff Lang0d8b7242015-09-09 14:56:53 -04002110 // Update the format caps based on the client version and extensions.
2111 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2112 // ES3.
2113 formatCaps.texturable =
2114 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2115 formatCaps.renderable =
2116 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2117 formatCaps.filterable =
2118 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002119
2120 // OpenGL ES does not support multisampling with integer formats
2121 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002122 {
Geoff Langd87878e2014-09-19 15:42:59 -04002123 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002124 }
Geoff Langd87878e2014-09-19 15:42:59 -04002125
2126 if (formatCaps.texturable && formatInfo.compressed)
2127 {
2128 mCaps.compressedTextureFormats.push_back(format);
2129 }
2130
2131 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002132 }
2133}
2134
Jamie Madill1b94d432015-08-07 13:23:23 -04002135void Context::syncRendererState()
2136{
2137 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002138 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002139 mState.clearDirtyBits();
2140 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002141}
2142
Jamie Madillad9f24e2016-02-12 09:27:24 -05002143void Context::syncRendererState(const State::DirtyBits &bitMask,
2144 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002145{
2146 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002147 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002148 mState.clearDirtyBits(dirtyBits);
2149
Jamie Madillad9f24e2016-02-12 09:27:24 -05002150 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002151}
Jamie Madillc29968b2016-01-20 11:17:23 -05002152
2153void Context::blitFramebuffer(GLint srcX0,
2154 GLint srcY0,
2155 GLint srcX1,
2156 GLint srcY1,
2157 GLint dstX0,
2158 GLint dstY0,
2159 GLint dstX1,
2160 GLint dstY1,
2161 GLbitfield mask,
2162 GLenum filter)
2163{
Jamie Madillc29968b2016-01-20 11:17:23 -05002164 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2165 ASSERT(drawFramebuffer);
2166
2167 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2168 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2169
Jamie Madillad9f24e2016-02-12 09:27:24 -05002170 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002171
Jamie Madill8415b5f2016-04-26 13:41:39 -04002172 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173}
Jamie Madillc29968b2016-01-20 11:17:23 -05002174
2175void Context::clear(GLbitfield mask)
2176{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002177 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002178 handleError(mState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002179}
2180
2181void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2182{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002183 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002184 handleError(mState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2185 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002186}
2187
2188void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2189{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002190 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002191 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2192 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002193}
2194
2195void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2196{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002197 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002198 handleError(mState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2199 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002200}
2201
2202void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2203{
2204 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2205 ASSERT(framebufferObject);
2206
2207 // If a buffer is not present, the clear has no effect
2208 if (framebufferObject->getDepthbuffer() == nullptr &&
2209 framebufferObject->getStencilbuffer() == nullptr)
2210 {
2211 return;
2212 }
2213
Jamie Madillad9f24e2016-02-12 09:27:24 -05002214 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002215 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2216 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002217}
2218
2219void Context::readPixels(GLint x,
2220 GLint y,
2221 GLsizei width,
2222 GLsizei height,
2223 GLenum format,
2224 GLenum type,
2225 GLvoid *pixels)
2226{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002227 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002228
2229 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2230 ASSERT(framebufferObject);
2231
2232 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002233 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002234}
2235
2236void Context::copyTexImage2D(GLenum target,
2237 GLint level,
2238 GLenum internalformat,
2239 GLint x,
2240 GLint y,
2241 GLsizei width,
2242 GLsizei height,
2243 GLint border)
2244{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002245 // Only sync the read FBO
2246 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2247
Jamie Madillc29968b2016-01-20 11:17:23 -05002248 Rectangle sourceArea(x, y, width, height);
2249
2250 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2251 Texture *texture =
2252 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002253 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002254}
2255
2256void Context::copyTexSubImage2D(GLenum target,
2257 GLint level,
2258 GLint xoffset,
2259 GLint yoffset,
2260 GLint x,
2261 GLint y,
2262 GLsizei width,
2263 GLsizei height)
2264{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002265 // Only sync the read FBO
2266 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2267
Jamie Madillc29968b2016-01-20 11:17:23 -05002268 Offset destOffset(xoffset, yoffset, 0);
2269 Rectangle sourceArea(x, y, width, height);
2270
2271 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2272 Texture *texture =
2273 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002274 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002275}
2276
2277void Context::copyTexSubImage3D(GLenum target,
2278 GLint level,
2279 GLint xoffset,
2280 GLint yoffset,
2281 GLint zoffset,
2282 GLint x,
2283 GLint y,
2284 GLsizei width,
2285 GLsizei height)
2286{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002287 // Only sync the read FBO
2288 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2289
Jamie Madillc29968b2016-01-20 11:17:23 -05002290 Offset destOffset(xoffset, yoffset, zoffset);
2291 Rectangle sourceArea(x, y, width, height);
2292
2293 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2294 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002295 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002296}
2297
2298void Context::framebufferTexture2D(GLenum target,
2299 GLenum attachment,
2300 GLenum textarget,
2301 GLuint texture,
2302 GLint level)
2303{
2304 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2305 ASSERT(framebuffer);
2306
2307 if (texture != 0)
2308 {
2309 Texture *textureObj = getTexture(texture);
2310
2311 ImageIndex index = ImageIndex::MakeInvalid();
2312
2313 if (textarget == GL_TEXTURE_2D)
2314 {
2315 index = ImageIndex::Make2D(level);
2316 }
2317 else
2318 {
2319 ASSERT(IsCubeMapTextureTarget(textarget));
2320 index = ImageIndex::MakeCube(textarget, level);
2321 }
2322
2323 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2324 }
2325 else
2326 {
2327 framebuffer->resetAttachment(attachment);
2328 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002329
2330 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002331}
2332
2333void Context::framebufferRenderbuffer(GLenum target,
2334 GLenum attachment,
2335 GLenum renderbuffertarget,
2336 GLuint renderbuffer)
2337{
2338 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2339 ASSERT(framebuffer);
2340
2341 if (renderbuffer != 0)
2342 {
2343 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2344 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2345 renderbufferObject);
2346 }
2347 else
2348 {
2349 framebuffer->resetAttachment(attachment);
2350 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002351
2352 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002353}
2354
2355void Context::framebufferTextureLayer(GLenum target,
2356 GLenum attachment,
2357 GLuint texture,
2358 GLint level,
2359 GLint layer)
2360{
2361 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2362 ASSERT(framebuffer);
2363
2364 if (texture != 0)
2365 {
2366 Texture *textureObject = getTexture(texture);
2367
2368 ImageIndex index = ImageIndex::MakeInvalid();
2369
2370 if (textureObject->getTarget() == GL_TEXTURE_3D)
2371 {
2372 index = ImageIndex::Make3D(level, layer);
2373 }
2374 else
2375 {
2376 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2377 index = ImageIndex::Make2DArray(level, layer);
2378 }
2379
2380 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2381 }
2382 else
2383 {
2384 framebuffer->resetAttachment(attachment);
2385 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002386
2387 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002388}
2389
2390void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2391{
2392 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2393 ASSERT(framebuffer);
2394 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002395 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002396}
2397
2398void Context::readBuffer(GLenum mode)
2399{
2400 Framebuffer *readFBO = mState.getReadFramebuffer();
2401 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002402 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002403}
2404
2405void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2406{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002407 // Only sync the FBO
2408 mState.syncDirtyObject(target);
2409
Jamie Madillc29968b2016-01-20 11:17:23 -05002410 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2411 ASSERT(framebuffer);
2412
2413 // The specification isn't clear what should be done when the framebuffer isn't complete.
2414 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002415 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002416}
2417
2418void Context::invalidateFramebuffer(GLenum target,
2419 GLsizei numAttachments,
2420 const GLenum *attachments)
2421{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002422 // Only sync the FBO
2423 mState.syncDirtyObject(target);
2424
Jamie Madillc29968b2016-01-20 11:17:23 -05002425 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2426 ASSERT(framebuffer);
2427
Jamie Madill437fa652016-05-03 15:13:24 -04002428 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002429 {
Jamie Madill437fa652016-05-03 15:13:24 -04002430 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002431 }
Jamie Madill437fa652016-05-03 15:13:24 -04002432
2433 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002434}
2435
2436void Context::invalidateSubFramebuffer(GLenum target,
2437 GLsizei numAttachments,
2438 const GLenum *attachments,
2439 GLint x,
2440 GLint y,
2441 GLsizei width,
2442 GLsizei height)
2443{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002444 // Only sync the FBO
2445 mState.syncDirtyObject(target);
2446
Jamie Madillc29968b2016-01-20 11:17:23 -05002447 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2448 ASSERT(framebuffer);
2449
Jamie Madill437fa652016-05-03 15:13:24 -04002450 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002451 {
Jamie Madill437fa652016-05-03 15:13:24 -04002452 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 }
Jamie Madill437fa652016-05-03 15:13:24 -04002454
2455 Rectangle area(x, y, width, height);
2456 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002457}
2458
Jamie Madill73a84962016-02-12 09:27:23 -05002459void Context::texImage2D(GLenum target,
2460 GLint level,
2461 GLint internalformat,
2462 GLsizei width,
2463 GLsizei height,
2464 GLint border,
2465 GLenum format,
2466 GLenum type,
2467 const GLvoid *pixels)
2468{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002469 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002470
2471 Extents size(width, height, 1);
2472 Texture *texture =
2473 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002474 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2475 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002476}
2477
2478void Context::texImage3D(GLenum target,
2479 GLint level,
2480 GLint internalformat,
2481 GLsizei width,
2482 GLsizei height,
2483 GLsizei depth,
2484 GLint border,
2485 GLenum format,
2486 GLenum type,
2487 const GLvoid *pixels)
2488{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002489 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002490
2491 Extents size(width, height, depth);
2492 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002493 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2494 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002495}
2496
2497void Context::texSubImage2D(GLenum target,
2498 GLint level,
2499 GLint xoffset,
2500 GLint yoffset,
2501 GLsizei width,
2502 GLsizei height,
2503 GLenum format,
2504 GLenum type,
2505 const GLvoid *pixels)
2506{
2507 // Zero sized uploads are valid but no-ops
2508 if (width == 0 || height == 0)
2509 {
2510 return;
2511 }
2512
Jamie Madillad9f24e2016-02-12 09:27:24 -05002513 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002514
2515 Box area(xoffset, yoffset, 0, width, height, 1);
2516 Texture *texture =
2517 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002518 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2519 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002520}
2521
2522void Context::texSubImage3D(GLenum target,
2523 GLint level,
2524 GLint xoffset,
2525 GLint yoffset,
2526 GLint zoffset,
2527 GLsizei width,
2528 GLsizei height,
2529 GLsizei depth,
2530 GLenum format,
2531 GLenum type,
2532 const GLvoid *pixels)
2533{
2534 // Zero sized uploads are valid but no-ops
2535 if (width == 0 || height == 0 || depth == 0)
2536 {
2537 return;
2538 }
2539
Jamie Madillad9f24e2016-02-12 09:27:24 -05002540 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002541
2542 Box area(xoffset, yoffset, zoffset, width, height, depth);
2543 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002544 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2545 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002546}
2547
2548void Context::compressedTexImage2D(GLenum target,
2549 GLint level,
2550 GLenum internalformat,
2551 GLsizei width,
2552 GLsizei height,
2553 GLint border,
2554 GLsizei imageSize,
2555 const GLvoid *data)
2556{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002557 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002558
2559 Extents size(width, height, 1);
2560 Texture *texture =
2561 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002562 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2563 size, imageSize,
2564 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002565}
2566
2567void Context::compressedTexImage3D(GLenum target,
2568 GLint level,
2569 GLenum internalformat,
2570 GLsizei width,
2571 GLsizei height,
2572 GLsizei depth,
2573 GLint border,
2574 GLsizei imageSize,
2575 const GLvoid *data)
2576{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002577 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002578
2579 Extents size(width, height, depth);
2580 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002581 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2582 size, imageSize,
2583 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002584}
2585
2586void Context::compressedTexSubImage2D(GLenum target,
2587 GLint level,
2588 GLint xoffset,
2589 GLint yoffset,
2590 GLsizei width,
2591 GLsizei height,
2592 GLenum format,
2593 GLsizei imageSize,
2594 const GLvoid *data)
2595{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002596 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002597
2598 Box area(xoffset, yoffset, 0, width, height, 1);
2599 Texture *texture =
2600 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002601 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2602 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002603}
2604
2605void Context::compressedTexSubImage3D(GLenum target,
2606 GLint level,
2607 GLint xoffset,
2608 GLint yoffset,
2609 GLint zoffset,
2610 GLsizei width,
2611 GLsizei height,
2612 GLsizei depth,
2613 GLenum format,
2614 GLsizei imageSize,
2615 const GLvoid *data)
2616{
2617 // Zero sized uploads are valid but no-ops
2618 if (width == 0 || height == 0)
2619 {
2620 return;
2621 }
2622
Jamie Madillad9f24e2016-02-12 09:27:24 -05002623 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002624
2625 Box area(xoffset, yoffset, zoffset, width, height, depth);
2626 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002627 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2628 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002629}
2630
Olli Etuaho4f667482016-03-30 15:56:35 +03002631void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2632{
2633 Buffer *buffer = getState().getTargetBuffer(target);
2634 ASSERT(buffer);
2635
2636 if (!buffer->isMapped())
2637 {
2638 *params = nullptr;
2639 }
2640 else
2641 {
2642 *params = buffer->getMapPointer();
2643 }
2644}
2645
2646GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2647{
2648 Buffer *buffer = getState().getTargetBuffer(target);
2649 ASSERT(buffer);
2650
2651 Error error = buffer->map(access);
2652 if (error.isError())
2653 {
Jamie Madill437fa652016-05-03 15:13:24 -04002654 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002655 return nullptr;
2656 }
2657
2658 return buffer->getMapPointer();
2659}
2660
2661GLboolean Context::unmapBuffer(GLenum target)
2662{
2663 Buffer *buffer = getState().getTargetBuffer(target);
2664 ASSERT(buffer);
2665
2666 GLboolean result;
2667 Error error = buffer->unmap(&result);
2668 if (error.isError())
2669 {
Jamie Madill437fa652016-05-03 15:13:24 -04002670 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002671 return GL_FALSE;
2672 }
2673
2674 return result;
2675}
2676
2677GLvoid *Context::mapBufferRange(GLenum target,
2678 GLintptr offset,
2679 GLsizeiptr length,
2680 GLbitfield access)
2681{
2682 Buffer *buffer = getState().getTargetBuffer(target);
2683 ASSERT(buffer);
2684
2685 Error error = buffer->mapRange(offset, length, access);
2686 if (error.isError())
2687 {
Jamie Madill437fa652016-05-03 15:13:24 -04002688 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002689 return nullptr;
2690 }
2691
2692 return buffer->getMapPointer();
2693}
2694
2695void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2696{
2697 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2698}
2699
Jamie Madillad9f24e2016-02-12 09:27:24 -05002700void Context::syncStateForReadPixels()
2701{
2702 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2703}
2704
2705void Context::syncStateForTexImage()
2706{
2707 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2708}
2709
2710void Context::syncStateForClear()
2711{
2712 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2713}
2714
2715void Context::syncStateForBlit()
2716{
2717 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2718}
2719
Jamie Madillc29968b2016-01-20 11:17:23 -05002720} // namespace gl