blob: 683ec1868d69d11f9cd08f5ab4b06690af1a9292 [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"
34#include "libANGLE/renderer/Renderer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000035
Geoff Langf6db0982015-08-25 13:04:00 -040036namespace
37{
38
Ian Ewell3ffd78b2016-01-22 16:09:42 -050039template <typename T>
40gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
41{
42 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
43 ASSERT(queryObject != nullptr);
44
45 switch (pname)
46 {
47 case GL_QUERY_RESULT_EXT:
48 return queryObject->getResult(params);
49 case GL_QUERY_RESULT_AVAILABLE_EXT:
50 {
51 bool available;
52 gl::Error error = queryObject->isResultAvailable(&available);
53 if (!error.isError())
54 {
55 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
56 }
57 return error;
58 }
59 default:
60 UNREACHABLE();
61 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
62 }
63}
64
Geoff Langf6db0982015-08-25 13:04:00 -040065void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
66{
Geoff Lang1a683462015-09-29 15:09:59 -040067 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040068 {
69 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
70 tfBufferIndex++)
71 {
72 const OffsetBindingPointer<gl::Buffer> &buffer =
73 transformFeedback->getIndexedBuffer(tfBufferIndex);
74 if (buffer.get() != nullptr)
75 {
76 buffer->onTransformFeedback();
77 }
78 }
79 }
80}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050081
82// Attribute map queries.
83EGLint GetClientVersion(const egl::AttributeMap &attribs)
84{
Ian Ewellec2c0c52016-04-05 13:46:26 -040085 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -050086}
87
88GLenum GetResetStrategy(const egl::AttributeMap &attribs)
89{
Ian Ewellec2c0c52016-04-05 13:46:26 -040090 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
91 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -050092 switch (attrib)
93 {
94 case EGL_NO_RESET_NOTIFICATION:
95 return GL_NO_RESET_NOTIFICATION_EXT;
96 case EGL_LOSE_CONTEXT_ON_RESET:
97 return GL_LOSE_CONTEXT_ON_RESET_EXT;
98 default:
99 UNREACHABLE();
100 return GL_NONE;
101 }
102}
103
104bool GetRobustAccess(const egl::AttributeMap &attribs)
105{
106 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
107}
108
109bool GetDebug(const egl::AttributeMap &attribs)
110{
111 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
112}
113
114bool GetNoError(const egl::AttributeMap &attribs)
115{
116 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
117}
118
Geoff Langf6db0982015-08-25 13:04:00 -0400119} // anonymous namespace
120
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000121namespace gl
122{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000123
Corentin Wallez51706ea2015-08-07 14:39:22 -0400124Context::Context(const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400125 const Context *shareContext,
126 rx::Renderer *renderer,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500127 const egl::AttributeMap &attribs)
128 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500129 mState,
130 mCaps,
131 mTextureCaps,
132 mExtensions,
133 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500134 mLimitations,
135 GetNoError(attribs)),
136 mCompiler(nullptr),
Jamie Madillf25855c2015-11-03 11:06:18 -0500137 mRenderer(renderer),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400139 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140 mClientType(EGL_OPENGL_ES_API),
141 mHasBeenCurrent(false),
142 mContextLost(false),
143 mResetStatus(GL_NO_ERROR),
144 mResetStrategy(GetResetStrategy(attribs)),
145 mRobustAccess(GetRobustAccess(attribs)),
146 mCurrentSurface(nullptr),
147 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000148{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400152
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100154
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400156
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000157 if (shareContext != NULL)
158 {
159 mResourceManager = shareContext->mResourceManager;
160 mResourceManager->addRef();
161 }
162 else
163 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000164 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000165 }
166
Jamie Madillc185cb82015-04-28 12:39:08 -0400167 mData.resourceManager = mResourceManager;
168
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000169 // [OpenGL ES 2.0.24] section 3.7 page 83:
170 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
171 // and cube map texture state vectors respectively associated with them.
172 // In order that access to these initial textures not be lost, they are treated as texture
173 // objects all of whose names are 0.
174
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300175 Texture *zeroTexture2D = new Texture(mRenderer, 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500176 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500177
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300178 Texture *zeroTextureCube = new Texture(mRenderer, 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500179 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400180
181 if (mClientVersion >= 3)
182 {
183 // TODO: These could also be enabled via extension
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300184 Texture *zeroTexture3D = new Texture(mRenderer, 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500185 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400186
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300187 Texture *zeroTexture2DArray = new Texture(mRenderer, 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500188 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400189 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000190
Ian Ewellbda75592016-04-18 17:25:54 -0400191 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
192 {
193 Texture *zeroTextureExternal = new Texture(mRenderer, 0, GL_TEXTURE_EXTERNAL_OES);
194 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
195 }
196
Jamie Madille6382c32014-11-07 15:05:26 -0500197 mState.initializeZeroTextures(mZeroTextures);
198
Jamie Madill57a89722013-07-02 11:57:03 -0400199 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000200 bindArrayBuffer(0);
201 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400202
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000203 bindRenderbuffer(0);
204
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000205 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400206 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000207 {
208 bindIndexedUniformBuffer(0, i, 0, -1);
209 }
210
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000211 bindCopyReadBuffer(0);
212 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000213 bindPixelPackBuffer(0);
214 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000215
Geoff Lang1a683462015-09-29 15:09:59 -0400216 if (mClientVersion >= 3)
217 {
218 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
219 // In the initial state, a default transform feedback object is bound and treated as
220 // a transform feedback object with a name of zero. That object is bound any time
221 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400222 bindTransformFeedback(0);
223 }
Geoff Langc8058452014-02-03 12:04:11 -0500224
Jamie Madill83f349e2015-09-23 09:50:36 -0400225 mCompiler = new Compiler(mRenderer, getData());
Jamie Madillad9f24e2016-02-12 09:27:24 -0500226
227 // Initialize dirty bit masks
228 // TODO(jmadill): additional ES3 state
229 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
230 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
231 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
232 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
233 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
234 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400235 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500236 // No dirty objects.
237
238 // Readpixels uses the pack state and read FBO
239 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
240 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
241 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
242 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
243 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400244 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500245 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
246
247 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
248 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
249 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
250 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
251 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
252 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
253 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
254 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
255 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
256 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
257 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
258 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
259
260 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
261 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
262 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
263 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000264}
265
266Context::~Context()
267{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500268 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000269
Corentin Wallez37c39792015-08-20 14:19:46 -0400270 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000271 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400272 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400273 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400274 {
275 SafeDelete(framebuffer.second);
276 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 }
278
Corentin Wallez80b24112015-08-25 16:41:57 -0400279 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000280 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400281 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282 }
283
Corentin Wallez80b24112015-08-25 16:41:57 -0400284 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000285 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400286 if (query.second != nullptr)
287 {
288 query.second->release();
289 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000290 }
291
Corentin Wallez80b24112015-08-25 16:41:57 -0400292 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400293 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400294 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400295 }
296
Corentin Wallez80b24112015-08-25 16:41:57 -0400297 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500298 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500299 if (transformFeedback.second != nullptr)
300 {
301 transformFeedback.second->release();
302 }
Geoff Langc8058452014-02-03 12:04:11 -0500303 }
304
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400306 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500307 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400308 }
309 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000310
Corentin Wallez51706ea2015-08-07 14:39:22 -0400311 if (mCurrentSurface != nullptr)
312 {
313 releaseSurface();
314 }
315
Jamie Madill1e9ae072014-11-06 15:27:21 -0500316 if (mResourceManager)
317 {
318 mResourceManager->release();
319 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500320
321 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000322}
323
daniel@transgaming.comad629872012-11-28 19:32:06 +0000324void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000325{
Jamie Madill77a72f62015-04-14 11:18:32 -0400326 ASSERT(surface != nullptr);
327
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000328 if (!mHasBeenCurrent)
329 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400331 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332
Shannon Woods53a94a82014-06-24 15:20:36 -0400333 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
334 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000335
336 mHasBeenCurrent = true;
337 }
338
Jamie Madill1b94d432015-08-07 13:23:23 -0400339 // TODO(jmadill): Rework this when we support ContextImpl
340 mState.setAllDirtyBits();
341
Corentin Wallez51706ea2015-08-07 14:39:22 -0400342 if (mCurrentSurface)
343 {
344 releaseSurface();
345 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000346 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400347 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000348
Corentin Wallez37c39792015-08-20 14:19:46 -0400349 // Update default framebuffer, the binding of the previous default
350 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400351 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400352 Framebuffer *newDefault = surface->getDefaultFramebuffer();
353 if (mState.getReadFramebuffer() == nullptr)
354 {
355 mState.setReadFramebufferBinding(newDefault);
356 }
357 if (mState.getDrawFramebuffer() == nullptr)
358 {
359 mState.setDrawFramebufferBinding(newDefault);
360 }
361 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400362 }
Ian Ewell292f0052016-02-04 10:37:32 -0500363
364 // Notify the renderer of a context switch
365 mRenderer->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000366}
367
Jamie Madill77a72f62015-04-14 11:18:32 -0400368void Context::releaseSurface()
369{
Corentin Wallez37c39792015-08-20 14:19:46 -0400370 ASSERT(mCurrentSurface != nullptr);
371
372 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400373 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400374 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
375 if (mState.getReadFramebuffer() == currentDefault)
376 {
377 mState.setReadFramebufferBinding(nullptr);
378 }
379 if (mState.getDrawFramebuffer() == currentDefault)
380 {
381 mState.setDrawFramebufferBinding(nullptr);
382 }
383 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400384 }
385
Corentin Wallez51706ea2015-08-07 14:39:22 -0400386 mCurrentSurface->setIsCurrent(false);
387 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400388}
389
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000390// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000391void Context::markContextLost()
392{
393 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
394 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
395 mContextLost = true;
396}
397
398bool Context::isContextLost()
399{
400 return mContextLost;
401}
402
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000403GLuint Context::createBuffer()
404{
405 return mResourceManager->createBuffer();
406}
407
408GLuint Context::createProgram()
409{
410 return mResourceManager->createProgram();
411}
412
413GLuint Context::createShader(GLenum type)
414{
Jamie Madill006cbc52015-09-23 16:47:54 -0400415 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000416}
417
418GLuint Context::createTexture()
419{
420 return mResourceManager->createTexture();
421}
422
423GLuint Context::createRenderbuffer()
424{
425 return mResourceManager->createRenderbuffer();
426}
427
Geoff Lang882033e2014-09-30 11:26:07 -0400428GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400429{
430 GLuint handle = mResourceManager->createFenceSync();
431
Cooper Partind8e62a32015-01-29 15:21:25 -0800432 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400433}
434
Jamie Madill57a89722013-07-02 11:57:03 -0400435GLuint Context::createVertexArray()
436{
Geoff Lang36167ab2015-12-07 10:27:14 -0500437 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
438 mVertexArrayMap[vertexArray] = nullptr;
439 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400440}
441
Jamie Madilldc356042013-07-19 16:36:57 -0400442GLuint Context::createSampler()
443{
444 return mResourceManager->createSampler();
445}
446
Geoff Langc8058452014-02-03 12:04:11 -0500447GLuint Context::createTransformFeedback()
448{
Geoff Lang36167ab2015-12-07 10:27:14 -0500449 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
450 mTransformFeedbackMap[transformFeedback] = nullptr;
451 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500452}
453
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454// Returns an unused framebuffer name
455GLuint Context::createFramebuffer()
456{
457 GLuint handle = mFramebufferHandleAllocator.allocate();
458
459 mFramebufferMap[handle] = NULL;
460
461 return handle;
462}
463
Jamie Madill33dc8432013-07-26 11:55:05 -0400464GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465{
Jamie Madill33dc8432013-07-26 11:55:05 -0400466 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700468 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469
470 return handle;
471}
472
473// Returns an unused query name
474GLuint Context::createQuery()
475{
476 GLuint handle = mQueryHandleAllocator.allocate();
477
478 mQueryMap[handle] = NULL;
479
480 return handle;
481}
482
483void Context::deleteBuffer(GLuint buffer)
484{
485 if (mResourceManager->getBuffer(buffer))
486 {
487 detachBuffer(buffer);
488 }
Jamie Madill893ab082014-05-16 16:56:10 -0400489
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000490 mResourceManager->deleteBuffer(buffer);
491}
492
493void Context::deleteShader(GLuint shader)
494{
495 mResourceManager->deleteShader(shader);
496}
497
498void Context::deleteProgram(GLuint program)
499{
500 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000501}
502
503void Context::deleteTexture(GLuint texture)
504{
505 if (mResourceManager->getTexture(texture))
506 {
507 detachTexture(texture);
508 }
509
510 mResourceManager->deleteTexture(texture);
511}
512
513void Context::deleteRenderbuffer(GLuint renderbuffer)
514{
515 if (mResourceManager->getRenderbuffer(renderbuffer))
516 {
517 detachRenderbuffer(renderbuffer);
518 }
Jamie Madill893ab082014-05-16 16:56:10 -0400519
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000520 mResourceManager->deleteRenderbuffer(renderbuffer);
521}
522
Jamie Madillcd055f82013-07-26 11:55:15 -0400523void Context::deleteFenceSync(GLsync fenceSync)
524{
525 // The spec specifies the underlying Fence object is not deleted until all current
526 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
527 // and since our API is currently designed for being called from a single thread, we can delete
528 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700529 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400530}
531
Jamie Madill57a89722013-07-02 11:57:03 -0400532void Context::deleteVertexArray(GLuint vertexArray)
533{
Geoff Lang36167ab2015-12-07 10:27:14 -0500534 auto iter = mVertexArrayMap.find(vertexArray);
535 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000536 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500537 VertexArray *vertexArrayObject = iter->second;
538 if (vertexArrayObject != nullptr)
539 {
540 detachVertexArray(vertexArray);
541 delete vertexArrayObject;
542 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000543
Geoff Lang36167ab2015-12-07 10:27:14 -0500544 mVertexArrayMap.erase(iter);
545 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400546 }
547}
548
Jamie Madilldc356042013-07-19 16:36:57 -0400549void Context::deleteSampler(GLuint sampler)
550{
551 if (mResourceManager->getSampler(sampler))
552 {
553 detachSampler(sampler);
554 }
555
556 mResourceManager->deleteSampler(sampler);
557}
558
Geoff Langc8058452014-02-03 12:04:11 -0500559void Context::deleteTransformFeedback(GLuint transformFeedback)
560{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500561 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500562 if (iter != mTransformFeedbackMap.end())
563 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500564 TransformFeedback *transformFeedbackObject = iter->second;
565 if (transformFeedbackObject != nullptr)
566 {
567 detachTransformFeedback(transformFeedback);
568 transformFeedbackObject->release();
569 }
570
Geoff Lang50b3fe82015-12-08 14:49:12 +0000571 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500572 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500573 }
574}
575
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576void Context::deleteFramebuffer(GLuint framebuffer)
577{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500578 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579
580 if (framebufferObject != mFramebufferMap.end())
581 {
582 detachFramebuffer(framebuffer);
583
584 mFramebufferHandleAllocator.release(framebufferObject->first);
585 delete framebufferObject->second;
586 mFramebufferMap.erase(framebufferObject);
587 }
588}
589
Jamie Madill33dc8432013-07-26 11:55:05 -0400590void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500592 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593
Jamie Madill33dc8432013-07-26 11:55:05 -0400594 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400596 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400598 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 }
600}
601
602void Context::deleteQuery(GLuint query)
603{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500604 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605 if (queryObject != mQueryMap.end())
606 {
607 mQueryHandleAllocator.release(queryObject->first);
608 if (queryObject->second)
609 {
610 queryObject->second->release();
611 }
612 mQueryMap.erase(queryObject);
613 }
614}
615
Geoff Lang70d0f492015-12-10 17:45:46 -0500616Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000617{
618 return mResourceManager->getBuffer(handle);
619}
620
Geoff Lang48dcae72014-02-05 16:28:24 -0500621Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000622{
623 return mResourceManager->getShader(handle);
624}
625
Geoff Lang48dcae72014-02-05 16:28:24 -0500626Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000627{
628 return mResourceManager->getProgram(handle);
629}
630
Jamie Madill570f7c82014-07-03 10:38:54 -0400631Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000632{
633 return mResourceManager->getTexture(handle);
634}
635
Geoff Lang70d0f492015-12-10 17:45:46 -0500636Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637{
638 return mResourceManager->getRenderbuffer(handle);
639}
640
Jamie Madillcd055f82013-07-26 11:55:15 -0400641FenceSync *Context::getFenceSync(GLsync handle) const
642{
Minmin Gong794e0002015-04-07 18:31:54 -0700643 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400644}
645
Jamie Madill57a89722013-07-02 11:57:03 -0400646VertexArray *Context::getVertexArray(GLuint handle) const
647{
648 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500649 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400650}
651
Jamie Madilldc356042013-07-19 16:36:57 -0400652Sampler *Context::getSampler(GLuint handle) const
653{
654 return mResourceManager->getSampler(handle);
655}
656
Geoff Langc8058452014-02-03 12:04:11 -0500657TransformFeedback *Context::getTransformFeedback(GLuint handle) const
658{
Geoff Lang36167ab2015-12-07 10:27:14 -0500659 auto iter = mTransformFeedbackMap.find(handle);
660 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500661}
662
Geoff Lang70d0f492015-12-10 17:45:46 -0500663LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
664{
665 switch (identifier)
666 {
667 case GL_BUFFER:
668 return getBuffer(name);
669 case GL_SHADER:
670 return getShader(name);
671 case GL_PROGRAM:
672 return getProgram(name);
673 case GL_VERTEX_ARRAY:
674 return getVertexArray(name);
675 case GL_QUERY:
676 return getQuery(name);
677 case GL_TRANSFORM_FEEDBACK:
678 return getTransformFeedback(name);
679 case GL_SAMPLER:
680 return getSampler(name);
681 case GL_TEXTURE:
682 return getTexture(name);
683 case GL_RENDERBUFFER:
684 return getRenderbuffer(name);
685 case GL_FRAMEBUFFER:
686 return getFramebuffer(name);
687 default:
688 UNREACHABLE();
689 return nullptr;
690 }
691}
692
693LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
694{
695 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
696}
697
Jamie Madilldc356042013-07-19 16:36:57 -0400698bool Context::isSampler(GLuint samplerName) const
699{
700 return mResourceManager->isSampler(samplerName);
701}
702
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500703void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000704{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500705 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
706 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000707}
708
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000710{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500711 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
712 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000713}
714
Jamie Madilldedd7b92014-11-05 16:30:36 -0500715void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000716{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500717 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000718
Jamie Madilldedd7b92014-11-05 16:30:36 -0500719 if (handle == 0)
720 {
721 texture = mZeroTextures[target].get();
722 }
723 else
724 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500725 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500726 }
727
728 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500729 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000730}
731
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500732void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000733{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500734 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
735 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000736}
737
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500738void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000739{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500740 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
741 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000742}
743
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500744void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000745{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500746 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
747 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000748}
749
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500750void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400751{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500752 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
753 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400754}
755
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500756void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400757{
Geoff Lang76b10c92014-09-05 16:28:14 -0400758 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500759 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
760 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400761}
762
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500763void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000764{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500765 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
766 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000767}
768
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500769void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
770 GLuint index,
771 GLintptr offset,
772 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000773{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500774 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
775 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000776}
777
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500778void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000779{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500780 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
781 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000782}
783
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500784void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
785 GLuint index,
786 GLintptr offset,
787 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000788{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500789 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
790 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000791}
792
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500793void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000794{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500795 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
796 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000797}
798
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000800{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500801 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
802 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000803}
804
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500805void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000806{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500807 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
808 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000809}
810
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500811void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000812{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500813 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
814 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000815}
816
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000817void Context::useProgram(GLuint program)
818{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500819 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000820}
821
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500822void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500823{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500824 TransformFeedback *transformFeedback =
825 checkTransformFeedbackAllocation(transformFeedbackHandle);
826 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500827}
828
Geoff Lang5aad9672014-09-08 11:10:42 -0400829Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000830{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400832 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000833
Geoff Lang5aad9672014-09-08 11:10:42 -0400834 // begin query
835 Error error = queryObject->begin();
836 if (error.isError())
837 {
838 return error;
839 }
840
841 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400842 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843
Geoff Lang5aad9672014-09-08 11:10:42 -0400844 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845}
846
Geoff Lang5aad9672014-09-08 11:10:42 -0400847Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848{
Shannon Woods53a94a82014-06-24 15:20:36 -0400849 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400850 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851
Geoff Lang5aad9672014-09-08 11:10:42 -0400852 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000853
Geoff Lang5aad9672014-09-08 11:10:42 -0400854 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400855 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400856
857 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000858}
859
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500860Error Context::queryCounter(GLuint id, GLenum target)
861{
862 ASSERT(target == GL_TIMESTAMP_EXT);
863
864 Query *queryObject = getQuery(id, true, target);
865 ASSERT(queryObject);
866
867 return queryObject->queryCounter();
868}
869
870void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
871{
872 switch (pname)
873 {
874 case GL_CURRENT_QUERY_EXT:
875 params[0] = getState().getActiveQueryId(target);
876 break;
877 case GL_QUERY_COUNTER_BITS_EXT:
878 switch (target)
879 {
880 case GL_TIME_ELAPSED_EXT:
881 params[0] = getExtensions().queryCounterBitsTimeElapsed;
882 break;
883 case GL_TIMESTAMP_EXT:
884 params[0] = getExtensions().queryCounterBitsTimestamp;
885 break;
886 default:
887 UNREACHABLE();
888 params[0] = 0;
889 break;
890 }
891 break;
892 default:
893 UNREACHABLE();
894 return;
895 }
896}
897
898Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
899{
900 return GetQueryObjectParameter(this, id, pname, params);
901}
902
903Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
904{
905 return GetQueryObjectParameter(this, id, pname, params);
906}
907
908Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
909{
910 return GetQueryObjectParameter(this, id, pname, params);
911}
912
913Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
914{
915 return GetQueryObjectParameter(this, id, pname, params);
916}
917
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500918Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000919{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500920 auto framebufferIt = mFramebufferMap.find(handle);
921 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000922}
923
Jamie Madill33dc8432013-07-26 11:55:05 -0400924FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500926 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000927
Jamie Madill33dc8432013-07-26 11:55:05 -0400928 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929 {
930 return NULL;
931 }
932 else
933 {
934 return fence->second;
935 }
936}
937
938Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
939{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500940 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941
942 if (query == mQueryMap.end())
943 {
944 return NULL;
945 }
946 else
947 {
948 if (!query->second && create)
949 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700950 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951 query->second->addRef();
952 }
953 return query->second;
954 }
955}
956
Geoff Lang70d0f492015-12-10 17:45:46 -0500957Query *Context::getQuery(GLuint handle) const
958{
959 auto iter = mQueryMap.find(handle);
960 return (iter != mQueryMap.end()) ? iter->second : nullptr;
961}
962
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500963Texture *Context::getTargetTexture(GLenum target) const
964{
Ian Ewellbda75592016-04-18 17:25:54 -0400965 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500966 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000967}
968
Geoff Lang76b10c92014-09-05 16:28:14 -0400969Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500971 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972}
973
Geoff Lang492a7e42014-11-05 13:27:06 -0500974Compiler *Context::getCompiler() const
975{
976 return mCompiler;
977}
978
Jamie Madill893ab082014-05-16 16:56:10 -0400979void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980{
981 switch (pname)
982 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000983 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000984 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400986 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400987 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989}
990
Jamie Madill893ab082014-05-16 16:56:10 -0400991void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992{
Shannon Woods53a94a82014-06-24 15:20:36 -0400993 // Queries about context capabilities and maximums are answered by Context.
994 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995 switch (pname)
996 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400998 params[0] = mCaps.minAliasedLineWidth;
999 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001000 break;
1001 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 params[0] = mCaps.minAliasedPointSize;
1003 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001005 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001006 ASSERT(mExtensions.textureFilterAnisotropic);
1007 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001008 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001009 case GL_MAX_TEXTURE_LOD_BIAS:
1010 *params = mCaps.maxLODBias;
1011 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001013 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001014 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001015 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016}
1017
Jamie Madill893ab082014-05-16 16:56:10 -04001018void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019{
Shannon Woods53a94a82014-06-24 15:20:36 -04001020 // Queries about context capabilities and maximums are answered by Context.
1021 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001022
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023 switch (pname)
1024 {
Geoff Lang301d1612014-07-09 10:34:37 -04001025 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1026 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1027 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001028 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1029 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1030 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001031 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1032 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1033 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001034 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001035 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1036 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1037 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001038 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001039 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001040 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1041 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1042 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1043 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001044 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1045 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001046 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1047 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001048 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001049 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1050 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1051 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1052 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001053 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1054 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001055 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1056 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001057 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1058 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1059 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001060 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1061 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1062 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001063 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001064 case GL_MAX_VIEWPORT_DIMS:
1065 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001066 params[0] = mCaps.maxViewportWidth;
1067 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 }
1069 break;
1070 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001071 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001073 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1074 *params = mResetStrategy;
1075 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001076 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001077 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001079 case GL_SHADER_BINARY_FORMATS:
1080 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1081 break;
1082 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001083 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001084 break;
1085 case GL_PROGRAM_BINARY_FORMATS:
1086 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001088 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001089 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001090 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001091
1092 // GL_KHR_debug
1093 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1094 *params = mExtensions.maxDebugMessageLength;
1095 break;
1096 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1097 *params = mExtensions.maxDebugLoggedMessages;
1098 break;
1099 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1100 *params = mExtensions.maxDebugGroupStackDepth;
1101 break;
1102 case GL_MAX_LABEL_LENGTH:
1103 *params = mExtensions.maxLabelLength;
1104 break;
1105
Ian Ewell53f59f42016-01-28 17:36:55 -05001106 // GL_EXT_disjoint_timer_query
1107 case GL_GPU_DISJOINT_EXT:
1108 *params = mRenderer->getGPUDisjoint();
1109 break;
1110
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001112 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001113 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001114 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115}
1116
Jamie Madill893ab082014-05-16 16:56:10 -04001117void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001118{
Shannon Woods53a94a82014-06-24 15:20:36 -04001119 // Queries about context capabilities and maximums are answered by Context.
1120 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001121 switch (pname)
1122 {
1123 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001124 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001125 break;
1126 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001127 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001128 break;
1129 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001130 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001131 break;
1132 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001133 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001134 break;
1135 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001136 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001137 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001138
1139 // GL_EXT_disjoint_timer_query
1140 case GL_TIMESTAMP_EXT:
1141 *params = mRenderer->getTimestamp();
1142 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001143 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001144 UNREACHABLE();
1145 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001146 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001147}
1148
Geoff Lang70d0f492015-12-10 17:45:46 -05001149void Context::getPointerv(GLenum pname, void **params) const
1150{
1151 mState.getPointerv(pname, params);
1152}
1153
Shannon Woods1b2fb852013-08-19 14:28:48 -04001154bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1155{
Shannon Woods53a94a82014-06-24 15:20:36 -04001156 // Queries about context capabilities and maximums are answered by Context.
1157 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001158 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001159 // mere passthrough.
1160 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001161}
1162
1163bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1164{
Shannon Woods53a94a82014-06-24 15:20:36 -04001165 // Queries about context capabilities and maximums are answered by Context.
1166 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001167 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001168 // mere passthrough.
1169 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001170}
1171
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001172bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1173{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001174 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1175 {
1176 *type = GL_INT;
1177 *numParams = 1;
1178 return true;
1179 }
1180
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1182 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1183 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001184 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1186 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1187 // application.
1188 switch (pname)
1189 {
1190 case GL_COMPRESSED_TEXTURE_FORMATS:
1191 {
1192 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001193 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001194 }
1195 return true;
1196 case GL_PROGRAM_BINARY_FORMATS_OES:
1197 {
1198 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001199 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001200 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001201 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001202 case GL_SHADER_BINARY_FORMATS:
1203 {
1204 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001205 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001207 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001208
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001209 case GL_MAX_VERTEX_ATTRIBS:
1210 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1211 case GL_MAX_VARYING_VECTORS:
1212 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1213 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1214 case GL_MAX_TEXTURE_IMAGE_UNITS:
1215 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1216 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001217 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001218 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001219 case GL_NUM_SHADER_BINARY_FORMATS:
1220 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1221 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001222 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1223 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1224 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 case GL_RENDERBUFFER_BINDING:
1226 case GL_CURRENT_PROGRAM:
1227 case GL_PACK_ALIGNMENT:
1228 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1229 case GL_UNPACK_ALIGNMENT:
1230 case GL_GENERATE_MIPMAP_HINT:
1231 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1232 case GL_RED_BITS:
1233 case GL_GREEN_BITS:
1234 case GL_BLUE_BITS:
1235 case GL_ALPHA_BITS:
1236 case GL_DEPTH_BITS:
1237 case GL_STENCIL_BITS:
1238 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1239 case GL_CULL_FACE_MODE:
1240 case GL_FRONT_FACE:
1241 case GL_ACTIVE_TEXTURE:
1242 case GL_STENCIL_FUNC:
1243 case GL_STENCIL_VALUE_MASK:
1244 case GL_STENCIL_REF:
1245 case GL_STENCIL_FAIL:
1246 case GL_STENCIL_PASS_DEPTH_FAIL:
1247 case GL_STENCIL_PASS_DEPTH_PASS:
1248 case GL_STENCIL_BACK_FUNC:
1249 case GL_STENCIL_BACK_VALUE_MASK:
1250 case GL_STENCIL_BACK_REF:
1251 case GL_STENCIL_BACK_FAIL:
1252 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1253 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1254 case GL_DEPTH_FUNC:
1255 case GL_BLEND_SRC_RGB:
1256 case GL_BLEND_SRC_ALPHA:
1257 case GL_BLEND_DST_RGB:
1258 case GL_BLEND_DST_ALPHA:
1259 case GL_BLEND_EQUATION_RGB:
1260 case GL_BLEND_EQUATION_ALPHA:
1261 case GL_STENCIL_WRITEMASK:
1262 case GL_STENCIL_BACK_WRITEMASK:
1263 case GL_STENCIL_CLEAR_VALUE:
1264 case GL_SUBPIXEL_BITS:
1265 case GL_MAX_TEXTURE_SIZE:
1266 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1267 case GL_SAMPLE_BUFFERS:
1268 case GL_SAMPLES:
1269 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1270 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1271 case GL_TEXTURE_BINDING_2D:
1272 case GL_TEXTURE_BINDING_CUBE_MAP:
1273 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1274 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 {
1276 *type = GL_INT;
1277 *numParams = 1;
1278 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001279 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001280 case GL_MAX_SAMPLES_ANGLE:
1281 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001282 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001283 {
1284 *type = GL_INT;
1285 *numParams = 1;
1286 }
1287 else
1288 {
1289 return false;
1290 }
1291 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001292 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001293 case GL_MAX_VIEWPORT_DIMS:
1294 {
1295 *type = GL_INT;
1296 *numParams = 2;
1297 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001298 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299 case GL_VIEWPORT:
1300 case GL_SCISSOR_BOX:
1301 {
1302 *type = GL_INT;
1303 *numParams = 4;
1304 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001305 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001306 case GL_SHADER_COMPILER:
1307 case GL_SAMPLE_COVERAGE_INVERT:
1308 case GL_DEPTH_WRITEMASK:
1309 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1310 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1311 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1312 case GL_SAMPLE_COVERAGE:
1313 case GL_SCISSOR_TEST:
1314 case GL_STENCIL_TEST:
1315 case GL_DEPTH_TEST:
1316 case GL_BLEND:
1317 case GL_DITHER:
1318 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1319 {
1320 *type = GL_BOOL;
1321 *numParams = 1;
1322 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001323 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001324 case GL_COLOR_WRITEMASK:
1325 {
1326 *type = GL_BOOL;
1327 *numParams = 4;
1328 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001329 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 case GL_POLYGON_OFFSET_FACTOR:
1331 case GL_POLYGON_OFFSET_UNITS:
1332 case GL_SAMPLE_COVERAGE_VALUE:
1333 case GL_DEPTH_CLEAR_VALUE:
1334 case GL_LINE_WIDTH:
1335 {
1336 *type = GL_FLOAT;
1337 *numParams = 1;
1338 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001339 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001340 case GL_ALIASED_LINE_WIDTH_RANGE:
1341 case GL_ALIASED_POINT_SIZE_RANGE:
1342 case GL_DEPTH_RANGE:
1343 {
1344 *type = GL_FLOAT;
1345 *numParams = 2;
1346 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001347 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001348 case GL_COLOR_CLEAR_VALUE:
1349 case GL_BLEND_COLOR:
1350 {
1351 *type = GL_FLOAT;
1352 *numParams = 4;
1353 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001354 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001355 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001356 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001357 {
1358 return false;
1359 }
1360 *type = GL_FLOAT;
1361 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001362 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001363 case GL_TIMESTAMP_EXT:
1364 if (!mExtensions.disjointTimerQuery)
1365 {
1366 return false;
1367 }
1368 *type = GL_INT_64_ANGLEX;
1369 *numParams = 1;
1370 return true;
1371 case GL_GPU_DISJOINT_EXT:
1372 if (!mExtensions.disjointTimerQuery)
1373 {
1374 return false;
1375 }
1376 *type = GL_INT;
1377 *numParams = 1;
1378 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001379 }
1380
Geoff Lang70d0f492015-12-10 17:45:46 -05001381 if (mExtensions.debug)
1382 {
1383 switch (pname)
1384 {
1385 case GL_DEBUG_LOGGED_MESSAGES:
1386 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1387 case GL_DEBUG_GROUP_STACK_DEPTH:
1388 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1389 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1390 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1391 case GL_MAX_LABEL_LENGTH:
1392 *type = GL_INT;
1393 *numParams = 1;
1394 return true;
1395
1396 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1397 case GL_DEBUG_OUTPUT:
1398 *type = GL_BOOL;
1399 *numParams = 1;
1400 return true;
1401 }
1402 }
1403
Austin Kinrossbc781f32015-10-26 09:27:38 -07001404 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1405 switch (pname)
1406 {
1407 case GL_PACK_ROW_LENGTH:
1408 case GL_PACK_SKIP_ROWS:
1409 case GL_PACK_SKIP_PIXELS:
1410 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1411 {
1412 return false;
1413 }
1414 *type = GL_INT;
1415 *numParams = 1;
1416 return true;
1417 case GL_UNPACK_ROW_LENGTH:
1418 case GL_UNPACK_SKIP_ROWS:
1419 case GL_UNPACK_SKIP_PIXELS:
1420 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1421 {
1422 return false;
1423 }
1424 *type = GL_INT;
1425 *numParams = 1;
1426 return true;
1427 case GL_VERTEX_ARRAY_BINDING:
1428 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1429 {
1430 return false;
1431 }
1432 *type = GL_INT;
1433 *numParams = 1;
1434 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001435 case GL_PIXEL_PACK_BUFFER_BINDING:
1436 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1437 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1438 {
1439 return false;
1440 }
1441 *type = GL_INT;
1442 *numParams = 1;
1443 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001444 }
1445
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001446 if (mClientVersion < 3)
1447 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001448 return false;
1449 }
1450
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001451 // Check for ES3.0+ parameter names
1452 switch (pname)
1453 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001454 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1455 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001456 case GL_UNIFORM_BUFFER_BINDING:
1457 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001458 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001459 case GL_COPY_READ_BUFFER_BINDING:
1460 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001461 case GL_SAMPLER_BINDING:
1462 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001463 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001464 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001465 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001466 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001467 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1468 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1469 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001470 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1471 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001472 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001473 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1474 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001475 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1476 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001477 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001478 case GL_MAJOR_VERSION:
1479 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001480 case GL_MAX_ELEMENTS_INDICES:
1481 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001482 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001483 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001484 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001485 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001486 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001487 {
1488 *type = GL_INT;
1489 *numParams = 1;
1490 }
1491 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001492
1493 case GL_MAX_ELEMENT_INDEX:
1494 case GL_MAX_UNIFORM_BLOCK_SIZE:
1495 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1496 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1497 case GL_MAX_SERVER_WAIT_TIMEOUT:
1498 {
1499 *type = GL_INT_64_ANGLEX;
1500 *numParams = 1;
1501 }
1502 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001503
1504 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001505 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001506 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001507 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001508 {
1509 *type = GL_BOOL;
1510 *numParams = 1;
1511 }
1512 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001513
1514 case GL_MAX_TEXTURE_LOD_BIAS:
1515 {
1516 *type = GL_FLOAT;
1517 *numParams = 1;
1518 }
1519 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001520 }
1521
1522 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001523}
1524
Shannon Woods1b2fb852013-08-19 14:28:48 -04001525bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1526{
1527 if (mClientVersion < 3)
1528 {
1529 return false;
1530 }
1531
1532 switch (target)
1533 {
1534 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1535 case GL_UNIFORM_BUFFER_BINDING:
1536 {
1537 *type = GL_INT;
1538 *numParams = 1;
1539 }
1540 return true;
1541 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1542 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1543 case GL_UNIFORM_BUFFER_START:
1544 case GL_UNIFORM_BUFFER_SIZE:
1545 {
1546 *type = GL_INT_64_ANGLEX;
1547 *numParams = 1;
1548 }
1549 }
1550
1551 return false;
1552}
1553
Geoff Langf6db0982015-08-25 13:04:00 -04001554Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001555{
Jamie Madill1b94d432015-08-07 13:23:23 -04001556 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001557 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001558 if (error.isError())
1559 {
1560 return error;
1561 }
1562
Geoff Langf6db0982015-08-25 13:04:00 -04001563 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001564
1565 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001566}
1567
Geoff Langf6db0982015-08-25 13:04:00 -04001568Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1569{
1570 syncRendererState();
1571 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1572 if (error.isError())
1573 {
1574 return error;
1575 }
1576
1577 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1578
1579 return Error(GL_NO_ERROR);
1580}
1581
1582Error Context::drawElements(GLenum mode,
1583 GLsizei count,
1584 GLenum type,
1585 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001586 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001587{
Jamie Madill1b94d432015-08-07 13:23:23 -04001588 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001589 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1590}
1591
1592Error Context::drawElementsInstanced(GLenum mode,
1593 GLsizei count,
1594 GLenum type,
1595 const GLvoid *indices,
1596 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001597 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001598{
1599 syncRendererState();
1600 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1601 indexRange);
1602}
1603
1604Error Context::drawRangeElements(GLenum mode,
1605 GLuint start,
1606 GLuint end,
1607 GLsizei count,
1608 GLenum type,
1609 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001610 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001611{
1612 syncRendererState();
1613 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1614 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001615}
1616
Geoff Lang129753a2015-01-09 16:52:09 -05001617Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001618{
Geoff Lang129753a2015-01-09 16:52:09 -05001619 return mRenderer->flush();
1620}
1621
1622Error Context::finish()
1623{
1624 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001625}
1626
Austin Kinross6ee1e782015-05-29 17:05:37 -07001627void Context::insertEventMarker(GLsizei length, const char *marker)
1628{
1629 ASSERT(mRenderer);
1630 mRenderer->insertEventMarker(length, marker);
1631}
1632
1633void Context::pushGroupMarker(GLsizei length, const char *marker)
1634{
1635 ASSERT(mRenderer);
1636 mRenderer->pushGroupMarker(length, marker);
1637}
1638
1639void Context::popGroupMarker()
1640{
1641 ASSERT(mRenderer);
1642 mRenderer->popGroupMarker();
1643}
1644
Geoff Langd8605522016-04-13 10:19:12 -04001645void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1646{
1647 Program *programObject = getProgram(program);
1648 ASSERT(programObject);
1649
1650 programObject->bindUniformLocation(location, name);
1651}
1652
Geoff Langda5777c2014-07-11 09:52:58 -04001653void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001654{
Geoff Langda5777c2014-07-11 09:52:58 -04001655 if (error.isError())
1656 {
1657 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001658
1659 if (!error.getMessage().empty())
1660 {
1661 auto &debug = mState.getDebug();
1662 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1663 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1664 }
Geoff Langda5777c2014-07-11 09:52:58 -04001665 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666}
1667
1668// Get one of the recorded errors and clear its flag, if any.
1669// [OpenGL ES 2.0.24] section 2.5 page 13.
1670GLenum Context::getError()
1671{
Geoff Langda5777c2014-07-11 09:52:58 -04001672 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673 {
Geoff Langda5777c2014-07-11 09:52:58 -04001674 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001675 }
Geoff Langda5777c2014-07-11 09:52:58 -04001676 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001677 {
Geoff Langda5777c2014-07-11 09:52:58 -04001678 GLenum error = *mErrors.begin();
1679 mErrors.erase(mErrors.begin());
1680 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001681 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682}
1683
1684GLenum Context::getResetStatus()
1685{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001686 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001687 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001688 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001689 // mResetStatus will be set by the markContextLost callback
1690 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001691 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001692 {
1693 mRenderer->notifyDeviceLost();
1694 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001695 }
1696
1697 GLenum status = mResetStatus;
1698
1699 if (mResetStatus != GL_NO_ERROR)
1700 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001701 ASSERT(mContextLost);
1702
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001703 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001704 {
1705 mResetStatus = GL_NO_ERROR;
1706 }
1707 }
Jamie Madill893ab082014-05-16 16:56:10 -04001708
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001709 return status;
1710}
1711
1712bool Context::isResetNotificationEnabled()
1713{
1714 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1715}
1716
Corentin Walleze3b10e82015-05-20 11:06:25 -04001717const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001718{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001719 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001720}
1721
1722EGLenum Context::getClientType() const
1723{
1724 return mClientType;
1725}
1726
1727EGLenum Context::getRenderBuffer() const
1728{
Corentin Wallez37c39792015-08-20 14:19:46 -04001729 auto framebufferIt = mFramebufferMap.find(0);
1730 if (framebufferIt != mFramebufferMap.end())
1731 {
1732 const Framebuffer *framebuffer = framebufferIt->second;
1733 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1734
1735 ASSERT(backAttachment != nullptr);
1736 return backAttachment->getSurface()->getRenderBuffer();
1737 }
1738 else
1739 {
1740 return EGL_NONE;
1741 }
Régis Fénéon83107972015-02-05 12:57:44 +01001742}
1743
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001744VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001745{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001746 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001747 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1748 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001749 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001750 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1751 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001752 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001753
1754 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001755}
1756
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001757TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001758{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001759 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001760 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1761 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001762 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001763 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1764 transformFeedback->addRef();
1765 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001766 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001767
1768 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001769}
1770
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001771Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1772{
1773 // Can be called from Bind without a prior call to Gen.
1774 auto framebufferIt = mFramebufferMap.find(framebuffer);
1775 bool neverCreated = framebufferIt == mFramebufferMap.end();
1776 if (neverCreated || framebufferIt->second == nullptr)
1777 {
1778 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1779 if (neverCreated)
1780 {
1781 mFramebufferHandleAllocator.reserve(framebuffer);
1782 mFramebufferMap[framebuffer] = newFBO;
1783 return newFBO;
1784 }
1785
1786 framebufferIt->second = newFBO;
1787 }
1788
1789 return framebufferIt->second;
1790}
1791
Geoff Lang36167ab2015-12-07 10:27:14 -05001792bool Context::isVertexArrayGenerated(GLuint vertexArray)
1793{
1794 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1795}
1796
1797bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1798{
1799 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1800}
1801
Shannon Woods53a94a82014-06-24 15:20:36 -04001802void Context::detachTexture(GLuint texture)
1803{
1804 // Simple pass-through to State's detachTexture method, as textures do not require
1805 // allocation map management either here or in the resource manager at detach time.
1806 // Zero textures are held by the Context, and we don't attempt to request them from
1807 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001808 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001809}
1810
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001811void Context::detachBuffer(GLuint buffer)
1812{
Yuly Novikov5807a532015-12-03 13:01:22 -05001813 // Simple pass-through to State's detachBuffer method, since
1814 // only buffer attachments to container objects that are bound to the current context
1815 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001816
Yuly Novikov5807a532015-12-03 13:01:22 -05001817 // [OpenGL ES 3.2] section 5.1.2 page 45:
1818 // Attachments to unbound container objects, such as
1819 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1820 // are not affected and continue to act as references on the deleted object
1821 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001822}
1823
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001824void Context::detachFramebuffer(GLuint framebuffer)
1825{
Shannon Woods53a94a82014-06-24 15:20:36 -04001826 // Framebuffer detachment is handled by Context, because 0 is a valid
1827 // Framebuffer object, and a pointer to it must be passed from Context
1828 // to State at binding time.
1829
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001830 // [OpenGL ES 2.0.24] section 4.4 page 107:
1831 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1832 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1833
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001834 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001835 {
1836 bindReadFramebuffer(0);
1837 }
1838
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001839 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001840 {
1841 bindDrawFramebuffer(0);
1842 }
1843}
1844
1845void Context::detachRenderbuffer(GLuint renderbuffer)
1846{
Shannon Woods53a94a82014-06-24 15:20:36 -04001847 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001848}
1849
Jamie Madill57a89722013-07-02 11:57:03 -04001850void Context::detachVertexArray(GLuint vertexArray)
1851{
Jamie Madill77a72f62015-04-14 11:18:32 -04001852 // Vertex array detachment is handled by Context, because 0 is a valid
1853 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001854 // binding time.
1855
Jamie Madill57a89722013-07-02 11:57:03 -04001856 // [OpenGL ES 3.0.2] section 2.10 page 43:
1857 // If a vertex array object that is currently bound is deleted, the binding
1858 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001859 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001860 {
1861 bindVertexArray(0);
1862 }
1863}
1864
Geoff Langc8058452014-02-03 12:04:11 -05001865void Context::detachTransformFeedback(GLuint transformFeedback)
1866{
Corentin Walleza2257da2016-04-19 16:43:12 -04001867 // Transform feedback detachment is handled by Context, because 0 is a valid
1868 // transform feedback, and a pointer to it must be passed from Context to State at
1869 // binding time.
1870
1871 // The OpenGL specification doesn't mention what should happen when the currently bound
1872 // transform feedback object is deleted. Since it is a container object, we treat it like
1873 // VAOs and FBOs and set the current bound transform feedback back to 0.
1874 if (mState.removeTransformFeedbackBinding(transformFeedback))
1875 {
1876 bindTransformFeedback(0);
1877 }
Geoff Langc8058452014-02-03 12:04:11 -05001878}
1879
Jamie Madilldc356042013-07-19 16:36:57 -04001880void Context::detachSampler(GLuint sampler)
1881{
Shannon Woods53a94a82014-06-24 15:20:36 -04001882 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001883}
1884
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001885void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1886{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001887 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001888}
1889
Jamie Madille29d1672013-07-19 16:36:57 -04001890void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1891{
1892 mResourceManager->checkSamplerAllocation(sampler);
1893
1894 Sampler *samplerObject = getSampler(sampler);
1895 ASSERT(samplerObject);
1896
Geoff Lang69cce582015-09-17 13:20:36 -04001897 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001898 switch (pname)
1899 {
Geoff Lang69cce582015-09-17 13:20:36 -04001900 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1901 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1902 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1903 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1904 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1905 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1906 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1907 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1908 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1909 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1910 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001911 }
Geoff Lang69cce582015-09-17 13:20:36 -04001912 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001913}
1914
1915void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1916{
1917 mResourceManager->checkSamplerAllocation(sampler);
1918
1919 Sampler *samplerObject = getSampler(sampler);
1920 ASSERT(samplerObject);
1921
Geoff Lang69cce582015-09-17 13:20:36 -04001922 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001923 switch (pname)
1924 {
Geoff Lang69cce582015-09-17 13:20:36 -04001925 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1926 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1927 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1928 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1929 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1930 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1931 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1932 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1933 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1934 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1935 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001936 }
Geoff Lang69cce582015-09-17 13:20:36 -04001937 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001938}
1939
Jamie Madill9675b802013-07-19 16:36:59 -04001940GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1941{
1942 mResourceManager->checkSamplerAllocation(sampler);
1943
1944 Sampler *samplerObject = getSampler(sampler);
1945 ASSERT(samplerObject);
1946
Geoff Lang69cce582015-09-17 13:20:36 -04001947 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001948 switch (pname)
1949 {
Geoff Lang69cce582015-09-17 13:20:36 -04001950 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1951 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1952 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1953 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1954 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1955 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001956 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1957 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001958 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1959 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1960 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001961 }
Geoff Lang69cce582015-09-17 13:20:36 -04001962 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001963}
1964
1965GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1966{
1967 mResourceManager->checkSamplerAllocation(sampler);
1968
1969 Sampler *samplerObject = getSampler(sampler);
1970 ASSERT(samplerObject);
1971
Geoff Lang69cce582015-09-17 13:20:36 -04001972 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001973 switch (pname)
1974 {
Geoff Lang69cce582015-09-17 13:20:36 -04001975 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1976 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1977 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1978 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1979 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1980 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1981 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1982 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1983 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1984 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1985 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001986 }
Geoff Lang69cce582015-09-17 13:20:36 -04001987 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001988}
1989
Olli Etuahof0fee072016-03-30 15:11:58 +03001990void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1991{
1992 gl::Program *programObject = getProgram(program);
1993 ASSERT(programObject != nullptr);
1994
1995 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1996 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1997}
1998
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001999void Context::initRendererString()
2000{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002001 std::ostringstream rendererString;
2002 rendererString << "ANGLE (";
2003 rendererString << mRenderer->getRendererDescription();
2004 rendererString << ")";
2005
Geoff Langcec35902014-04-16 10:52:36 -04002006 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007}
2008
Geoff Langc0b9ef42014-07-02 10:02:37 -04002009const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002010{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002011 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012}
2013
Geoff Langcec35902014-04-16 10:52:36 -04002014void Context::initExtensionStrings()
2015{
Geoff Lang493daf52014-07-03 13:38:44 -04002016 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002017
Geoff Langc0b9ef42014-07-02 10:02:37 -04002018 std::ostringstream combinedStringStream;
2019 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2020 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002021}
2022
Geoff Langc0b9ef42014-07-02 10:02:37 -04002023const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002024{
2025 return mExtensionString;
2026}
2027
Geoff Langc0b9ef42014-07-02 10:02:37 -04002028const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002029{
2030 return mExtensionStrings[idx];
2031}
2032
2033size_t Context::getExtensionStringCount() const
2034{
2035 return mExtensionStrings.size();
2036}
2037
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002038void Context::beginTransformFeedback(GLenum primitiveMode)
2039{
2040 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2041 ASSERT(transformFeedback != nullptr);
2042 ASSERT(!transformFeedback->isPaused());
2043
2044 transformFeedback->begin(primitiveMode, getState().getProgram());
2045}
2046
2047bool Context::hasActiveTransformFeedback(GLuint program) const
2048{
2049 for (auto pair : mTransformFeedbackMap)
2050 {
2051 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2052 {
2053 return true;
2054 }
2055 }
2056 return false;
2057}
2058
Geoff Lang493daf52014-07-03 13:38:44 -04002059void Context::initCaps(GLuint clientVersion)
2060{
2061 mCaps = mRenderer->getRendererCaps();
2062
2063 mExtensions = mRenderer->getRendererExtensions();
2064
Austin Kinross02df7962015-07-01 10:03:42 -07002065 mLimitations = mRenderer->getRendererLimitations();
2066
Geoff Lang493daf52014-07-03 13:38:44 -04002067 if (clientVersion < 3)
2068 {
2069 // Disable ES3+ extensions
2070 mExtensions.colorBufferFloat = false;
2071 }
2072
2073 if (clientVersion > 2)
2074 {
2075 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2076 //mExtensions.sRGB = false;
2077 }
2078
Geoff Lang70d0f492015-12-10 17:45:46 -05002079 // Explicitly enable GL_KHR_debug
2080 mExtensions.debug = true;
2081 mExtensions.maxDebugMessageLength = 1024;
2082 mExtensions.maxDebugLoggedMessages = 1024;
2083 mExtensions.maxDebugGroupStackDepth = 1024;
2084 mExtensions.maxLabelLength = 1024;
2085
Geoff Lang301d1612014-07-09 10:34:37 -04002086 // Apply implementation limits
2087 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002088 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2089 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2090
2091 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002092
Geoff Lang900013c2014-07-07 11:32:19 -04002093 mCaps.compressedTextureFormats.clear();
2094
Geoff Lang493daf52014-07-03 13:38:44 -04002095 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2096 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2097 {
2098 GLenum format = i->first;
2099 TextureCaps formatCaps = i->second;
2100
Geoff Lang5d601382014-07-22 15:14:06 -04002101 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002102
Geoff Lang0d8b7242015-09-09 14:56:53 -04002103 // Update the format caps based on the client version and extensions.
2104 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2105 // ES3.
2106 formatCaps.texturable =
2107 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2108 formatCaps.renderable =
2109 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2110 formatCaps.filterable =
2111 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002112
2113 // OpenGL ES does not support multisampling with integer formats
2114 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002115 {
Geoff Langd87878e2014-09-19 15:42:59 -04002116 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002117 }
Geoff Langd87878e2014-09-19 15:42:59 -04002118
2119 if (formatCaps.texturable && formatInfo.compressed)
2120 {
2121 mCaps.compressedTextureFormats.push_back(format);
2122 }
2123
2124 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002125 }
2126}
2127
Jamie Madill1b94d432015-08-07 13:23:23 -04002128void Context::syncRendererState()
2129{
2130 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002131 mRenderer->syncState(mState, dirtyBits);
2132 mState.clearDirtyBits();
2133 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002134}
2135
Jamie Madillad9f24e2016-02-12 09:27:24 -05002136void Context::syncRendererState(const State::DirtyBits &bitMask,
2137 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002138{
2139 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002140 mRenderer->syncState(mState, dirtyBits);
2141 mState.clearDirtyBits(dirtyBits);
2142
Jamie Madillad9f24e2016-02-12 09:27:24 -05002143 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002144}
Jamie Madillc29968b2016-01-20 11:17:23 -05002145
2146void Context::blitFramebuffer(GLint srcX0,
2147 GLint srcY0,
2148 GLint srcX1,
2149 GLint srcY1,
2150 GLint dstX0,
2151 GLint dstY0,
2152 GLint dstX1,
2153 GLint dstY1,
2154 GLbitfield mask,
2155 GLenum filter)
2156{
2157 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2158 ASSERT(readFramebuffer);
2159
2160 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2161 ASSERT(drawFramebuffer);
2162
2163 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2164 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2165
Jamie Madillad9f24e2016-02-12 09:27:24 -05002166 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002167
2168 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2169 if (error.isError())
2170 {
2171 recordError(error);
2172 return;
2173 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002174}
Jamie Madillc29968b2016-01-20 11:17:23 -05002175
2176void Context::clear(GLbitfield mask)
2177{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002178 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002179
2180 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2181 if (error.isError())
2182 {
2183 recordError(error);
2184 }
2185}
2186
2187void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2188{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002189 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002190
2191 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2192 if (error.isError())
2193 {
2194 recordError(error);
2195 }
2196}
2197
2198void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2199{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002200 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002201
2202 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2203 if (error.isError())
2204 {
2205 recordError(error);
2206 }
2207}
2208
2209void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2210{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002211 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002212
2213 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2214 if (error.isError())
2215 {
2216 recordError(error);
2217 }
2218}
2219
2220void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2221{
2222 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2223 ASSERT(framebufferObject);
2224
2225 // If a buffer is not present, the clear has no effect
2226 if (framebufferObject->getDepthbuffer() == nullptr &&
2227 framebufferObject->getStencilbuffer() == nullptr)
2228 {
2229 return;
2230 }
2231
Jamie Madillad9f24e2016-02-12 09:27:24 -05002232 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002233
2234 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2235 if (error.isError())
2236 {
2237 recordError(error);
2238 }
2239}
2240
2241void Context::readPixels(GLint x,
2242 GLint y,
2243 GLsizei width,
2244 GLsizei height,
2245 GLenum format,
2246 GLenum type,
2247 GLvoid *pixels)
2248{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002249 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002250
2251 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2252 ASSERT(framebufferObject);
2253
2254 Rectangle area(x, y, width, height);
2255 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2256 if (error.isError())
2257 {
2258 recordError(error);
2259 }
2260}
2261
2262void Context::copyTexImage2D(GLenum target,
2263 GLint level,
2264 GLenum internalformat,
2265 GLint x,
2266 GLint y,
2267 GLsizei width,
2268 GLsizei height,
2269 GLint border)
2270{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002271 // Only sync the read FBO
2272 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2273
Jamie Madillc29968b2016-01-20 11:17:23 -05002274 Rectangle sourceArea(x, y, width, height);
2275
2276 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2277 Texture *texture =
2278 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2279 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2280 if (error.isError())
2281 {
2282 recordError(error);
2283 }
2284}
2285
2286void Context::copyTexSubImage2D(GLenum target,
2287 GLint level,
2288 GLint xoffset,
2289 GLint yoffset,
2290 GLint x,
2291 GLint y,
2292 GLsizei width,
2293 GLsizei height)
2294{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002295 // Only sync the read FBO
2296 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2297
Jamie Madillc29968b2016-01-20 11:17:23 -05002298 Offset destOffset(xoffset, yoffset, 0);
2299 Rectangle sourceArea(x, y, width, height);
2300
2301 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2302 Texture *texture =
2303 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2304 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2305 if (error.isError())
2306 {
2307 recordError(error);
2308 }
2309}
2310
2311void Context::copyTexSubImage3D(GLenum target,
2312 GLint level,
2313 GLint xoffset,
2314 GLint yoffset,
2315 GLint zoffset,
2316 GLint x,
2317 GLint y,
2318 GLsizei width,
2319 GLsizei height)
2320{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002321 // Only sync the read FBO
2322 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2323
Jamie Madillc29968b2016-01-20 11:17:23 -05002324 Offset destOffset(xoffset, yoffset, zoffset);
2325 Rectangle sourceArea(x, y, width, height);
2326
2327 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2328 Texture *texture = getTargetTexture(target);
2329 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2330 if (error.isError())
2331 {
2332 recordError(error);
2333 }
2334}
2335
2336void Context::framebufferTexture2D(GLenum target,
2337 GLenum attachment,
2338 GLenum textarget,
2339 GLuint texture,
2340 GLint level)
2341{
2342 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2343 ASSERT(framebuffer);
2344
2345 if (texture != 0)
2346 {
2347 Texture *textureObj = getTexture(texture);
2348
2349 ImageIndex index = ImageIndex::MakeInvalid();
2350
2351 if (textarget == GL_TEXTURE_2D)
2352 {
2353 index = ImageIndex::Make2D(level);
2354 }
2355 else
2356 {
2357 ASSERT(IsCubeMapTextureTarget(textarget));
2358 index = ImageIndex::MakeCube(textarget, level);
2359 }
2360
2361 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2362 }
2363 else
2364 {
2365 framebuffer->resetAttachment(attachment);
2366 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002367
2368 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002369}
2370
2371void Context::framebufferRenderbuffer(GLenum target,
2372 GLenum attachment,
2373 GLenum renderbuffertarget,
2374 GLuint renderbuffer)
2375{
2376 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2377 ASSERT(framebuffer);
2378
2379 if (renderbuffer != 0)
2380 {
2381 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2382 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2383 renderbufferObject);
2384 }
2385 else
2386 {
2387 framebuffer->resetAttachment(attachment);
2388 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002389
2390 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002391}
2392
2393void Context::framebufferTextureLayer(GLenum target,
2394 GLenum attachment,
2395 GLuint texture,
2396 GLint level,
2397 GLint layer)
2398{
2399 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2400 ASSERT(framebuffer);
2401
2402 if (texture != 0)
2403 {
2404 Texture *textureObject = getTexture(texture);
2405
2406 ImageIndex index = ImageIndex::MakeInvalid();
2407
2408 if (textureObject->getTarget() == GL_TEXTURE_3D)
2409 {
2410 index = ImageIndex::Make3D(level, layer);
2411 }
2412 else
2413 {
2414 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2415 index = ImageIndex::Make2DArray(level, layer);
2416 }
2417
2418 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2419 }
2420 else
2421 {
2422 framebuffer->resetAttachment(attachment);
2423 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002424
2425 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002426}
2427
2428void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2429{
2430 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2431 ASSERT(framebuffer);
2432 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002433 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002434}
2435
2436void Context::readBuffer(GLenum mode)
2437{
2438 Framebuffer *readFBO = mState.getReadFramebuffer();
2439 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002440 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002441}
2442
2443void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2444{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002445 // Only sync the FBO
2446 mState.syncDirtyObject(target);
2447
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2449 ASSERT(framebuffer);
2450
2451 // The specification isn't clear what should be done when the framebuffer isn't complete.
2452 // We leave it up to the framebuffer implementation to decide what to do.
2453 Error error = framebuffer->discard(numAttachments, attachments);
2454 if (error.isError())
2455 {
2456 recordError(error);
2457 }
2458}
2459
2460void Context::invalidateFramebuffer(GLenum target,
2461 GLsizei numAttachments,
2462 const GLenum *attachments)
2463{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002464 // Only sync the FBO
2465 mState.syncDirtyObject(target);
2466
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2468 ASSERT(framebuffer);
2469
2470 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2471 {
2472 Error error = framebuffer->invalidate(numAttachments, attachments);
2473 if (error.isError())
2474 {
2475 recordError(error);
2476 return;
2477 }
2478 }
2479}
2480
2481void Context::invalidateSubFramebuffer(GLenum target,
2482 GLsizei numAttachments,
2483 const GLenum *attachments,
2484 GLint x,
2485 GLint y,
2486 GLsizei width,
2487 GLsizei height)
2488{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002489 // Only sync the FBO
2490 mState.syncDirtyObject(target);
2491
Jamie Madillc29968b2016-01-20 11:17:23 -05002492 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2493 ASSERT(framebuffer);
2494
2495 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2496 {
2497 Rectangle area(x, y, width, height);
2498 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2499 if (error.isError())
2500 {
2501 recordError(error);
2502 return;
2503 }
2504 }
2505}
2506
Jamie Madill73a84962016-02-12 09:27:23 -05002507void Context::texImage2D(GLenum target,
2508 GLint level,
2509 GLint internalformat,
2510 GLsizei width,
2511 GLsizei height,
2512 GLint border,
2513 GLenum format,
2514 GLenum type,
2515 const GLvoid *pixels)
2516{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002517 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002518
2519 Extents size(width, height, 1);
2520 Texture *texture =
2521 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2522 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2523 format, type, reinterpret_cast<const uint8_t *>(pixels));
2524 if (error.isError())
2525 {
2526 recordError(error);
2527 }
2528}
2529
2530void Context::texImage3D(GLenum target,
2531 GLint level,
2532 GLint internalformat,
2533 GLsizei width,
2534 GLsizei height,
2535 GLsizei depth,
2536 GLint border,
2537 GLenum format,
2538 GLenum type,
2539 const GLvoid *pixels)
2540{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002541 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002542
2543 Extents size(width, height, depth);
2544 Texture *texture = getTargetTexture(target);
2545 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2546 format, type, reinterpret_cast<const uint8_t *>(pixels));
2547 if (error.isError())
2548 {
2549 recordError(error);
2550 }
2551}
2552
2553void Context::texSubImage2D(GLenum target,
2554 GLint level,
2555 GLint xoffset,
2556 GLint yoffset,
2557 GLsizei width,
2558 GLsizei height,
2559 GLenum format,
2560 GLenum type,
2561 const GLvoid *pixels)
2562{
2563 // Zero sized uploads are valid but no-ops
2564 if (width == 0 || height == 0)
2565 {
2566 return;
2567 }
2568
Jamie Madillad9f24e2016-02-12 09:27:24 -05002569 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002570
2571 Box area(xoffset, yoffset, 0, width, height, 1);
2572 Texture *texture =
2573 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2574 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2575 reinterpret_cast<const uint8_t *>(pixels));
2576 if (error.isError())
2577 {
2578 recordError(error);
2579 }
2580}
2581
2582void Context::texSubImage3D(GLenum target,
2583 GLint level,
2584 GLint xoffset,
2585 GLint yoffset,
2586 GLint zoffset,
2587 GLsizei width,
2588 GLsizei height,
2589 GLsizei depth,
2590 GLenum format,
2591 GLenum type,
2592 const GLvoid *pixels)
2593{
2594 // Zero sized uploads are valid but no-ops
2595 if (width == 0 || height == 0 || depth == 0)
2596 {
2597 return;
2598 }
2599
Jamie Madillad9f24e2016-02-12 09:27:24 -05002600 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002601
2602 Box area(xoffset, yoffset, zoffset, width, height, depth);
2603 Texture *texture = getTargetTexture(target);
2604 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2605 reinterpret_cast<const uint8_t *>(pixels));
2606 if (error.isError())
2607 {
2608 recordError(error);
2609 }
2610}
2611
2612void Context::compressedTexImage2D(GLenum target,
2613 GLint level,
2614 GLenum internalformat,
2615 GLsizei width,
2616 GLsizei height,
2617 GLint border,
2618 GLsizei imageSize,
2619 const GLvoid *data)
2620{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002621 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002622
2623 Extents size(width, height, 1);
2624 Texture *texture =
2625 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2626 Error error =
2627 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2628 imageSize, reinterpret_cast<const uint8_t *>(data));
2629 if (error.isError())
2630 {
2631 recordError(error);
2632 }
2633}
2634
2635void Context::compressedTexImage3D(GLenum target,
2636 GLint level,
2637 GLenum internalformat,
2638 GLsizei width,
2639 GLsizei height,
2640 GLsizei depth,
2641 GLint border,
2642 GLsizei imageSize,
2643 const GLvoid *data)
2644{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002645 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002646
2647 Extents size(width, height, depth);
2648 Texture *texture = getTargetTexture(target);
2649 Error error =
2650 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2651 imageSize, reinterpret_cast<const uint8_t *>(data));
2652 if (error.isError())
2653 {
2654 recordError(error);
2655 }
2656}
2657
2658void Context::compressedTexSubImage2D(GLenum target,
2659 GLint level,
2660 GLint xoffset,
2661 GLint yoffset,
2662 GLsizei width,
2663 GLsizei height,
2664 GLenum format,
2665 GLsizei imageSize,
2666 const GLvoid *data)
2667{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002668 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002669
2670 Box area(xoffset, yoffset, 0, width, height, 1);
2671 Texture *texture =
2672 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2673 Error error =
2674 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2675 imageSize, reinterpret_cast<const uint8_t *>(data));
2676 if (error.isError())
2677 {
2678 recordError(error);
2679 }
2680}
2681
2682void Context::compressedTexSubImage3D(GLenum target,
2683 GLint level,
2684 GLint xoffset,
2685 GLint yoffset,
2686 GLint zoffset,
2687 GLsizei width,
2688 GLsizei height,
2689 GLsizei depth,
2690 GLenum format,
2691 GLsizei imageSize,
2692 const GLvoid *data)
2693{
2694 // Zero sized uploads are valid but no-ops
2695 if (width == 0 || height == 0)
2696 {
2697 return;
2698 }
2699
Jamie Madillad9f24e2016-02-12 09:27:24 -05002700 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002701
2702 Box area(xoffset, yoffset, zoffset, width, height, depth);
2703 Texture *texture = getTargetTexture(target);
2704 Error error =
2705 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2706 imageSize, reinterpret_cast<const uint8_t *>(data));
2707 if (error.isError())
2708 {
2709 recordError(error);
2710 }
2711}
2712
Olli Etuaho4f667482016-03-30 15:56:35 +03002713void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2714{
2715 Buffer *buffer = getState().getTargetBuffer(target);
2716 ASSERT(buffer);
2717
2718 if (!buffer->isMapped())
2719 {
2720 *params = nullptr;
2721 }
2722 else
2723 {
2724 *params = buffer->getMapPointer();
2725 }
2726}
2727
2728GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2729{
2730 Buffer *buffer = getState().getTargetBuffer(target);
2731 ASSERT(buffer);
2732
2733 Error error = buffer->map(access);
2734 if (error.isError())
2735 {
2736 recordError(error);
2737 return nullptr;
2738 }
2739
2740 return buffer->getMapPointer();
2741}
2742
2743GLboolean Context::unmapBuffer(GLenum target)
2744{
2745 Buffer *buffer = getState().getTargetBuffer(target);
2746 ASSERT(buffer);
2747
2748 GLboolean result;
2749 Error error = buffer->unmap(&result);
2750 if (error.isError())
2751 {
2752 recordError(error);
2753 return GL_FALSE;
2754 }
2755
2756 return result;
2757}
2758
2759GLvoid *Context::mapBufferRange(GLenum target,
2760 GLintptr offset,
2761 GLsizeiptr length,
2762 GLbitfield access)
2763{
2764 Buffer *buffer = getState().getTargetBuffer(target);
2765 ASSERT(buffer);
2766
2767 Error error = buffer->mapRange(offset, length, access);
2768 if (error.isError())
2769 {
2770 recordError(error);
2771 return nullptr;
2772 }
2773
2774 return buffer->getMapPointer();
2775}
2776
2777void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2778{
2779 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2780}
2781
Jamie Madillad9f24e2016-02-12 09:27:24 -05002782void Context::syncStateForReadPixels()
2783{
2784 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2785}
2786
2787void Context::syncStateForTexImage()
2788{
2789 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2790}
2791
2792void Context::syncStateForClear()
2793{
2794 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2795}
2796
2797void Context::syncStateForBlit()
2798{
2799 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2800}
2801
Jamie Madillc29968b2016-01-20 11:17:23 -05002802} // namespace gl