blob: 26f737b1caa4d50d633bb813ce958424c8bb43ca [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);
235 // No dirty objects.
236
237 // Readpixels uses the pack state and read FBO
238 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
239 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
240 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
241 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
242 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
243 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
244
245 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
246 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
247 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
248 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
249 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
250 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
251 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
252 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
253 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
254 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
255 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
256 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
257
258 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
259 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
260 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
261 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000262}
263
264Context::~Context()
265{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500266 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000267
Corentin Wallez37c39792015-08-20 14:19:46 -0400268 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000269 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400270 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400271 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400272 {
273 SafeDelete(framebuffer.second);
274 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 }
276
Corentin Wallez80b24112015-08-25 16:41:57 -0400277 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400279 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000280 }
281
Corentin Wallez80b24112015-08-25 16:41:57 -0400282 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000283 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400284 if (query.second != nullptr)
285 {
286 query.second->release();
287 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288 }
289
Corentin Wallez80b24112015-08-25 16:41:57 -0400290 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400291 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400292 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400293 }
294
Corentin Wallez80b24112015-08-25 16:41:57 -0400295 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500296 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500297 if (transformFeedback.second != nullptr)
298 {
299 transformFeedback.second->release();
300 }
Geoff Langc8058452014-02-03 12:04:11 -0500301 }
302
Jamie Madilldedd7b92014-11-05 16:30:36 -0500303 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400304 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500305 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400306 }
307 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000308
Corentin Wallez51706ea2015-08-07 14:39:22 -0400309 if (mCurrentSurface != nullptr)
310 {
311 releaseSurface();
312 }
313
Jamie Madill1e9ae072014-11-06 15:27:21 -0500314 if (mResourceManager)
315 {
316 mResourceManager->release();
317 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500318
319 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000320}
321
daniel@transgaming.comad629872012-11-28 19:32:06 +0000322void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000323{
Jamie Madill77a72f62015-04-14 11:18:32 -0400324 ASSERT(surface != nullptr);
325
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326 if (!mHasBeenCurrent)
327 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000328 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400329 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000330
Shannon Woods53a94a82014-06-24 15:20:36 -0400331 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
332 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000333
334 mHasBeenCurrent = true;
335 }
336
Jamie Madill1b94d432015-08-07 13:23:23 -0400337 // TODO(jmadill): Rework this when we support ContextImpl
338 mState.setAllDirtyBits();
339
Corentin Wallez51706ea2015-08-07 14:39:22 -0400340 if (mCurrentSurface)
341 {
342 releaseSurface();
343 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000344 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400345 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000346
Corentin Wallez37c39792015-08-20 14:19:46 -0400347 // Update default framebuffer, the binding of the previous default
348 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400349 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400350 Framebuffer *newDefault = surface->getDefaultFramebuffer();
351 if (mState.getReadFramebuffer() == nullptr)
352 {
353 mState.setReadFramebufferBinding(newDefault);
354 }
355 if (mState.getDrawFramebuffer() == nullptr)
356 {
357 mState.setDrawFramebufferBinding(newDefault);
358 }
359 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400360 }
Ian Ewell292f0052016-02-04 10:37:32 -0500361
362 // Notify the renderer of a context switch
363 mRenderer->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000364}
365
Jamie Madill77a72f62015-04-14 11:18:32 -0400366void Context::releaseSurface()
367{
Corentin Wallez37c39792015-08-20 14:19:46 -0400368 ASSERT(mCurrentSurface != nullptr);
369
370 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400371 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400372 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
373 if (mState.getReadFramebuffer() == currentDefault)
374 {
375 mState.setReadFramebufferBinding(nullptr);
376 }
377 if (mState.getDrawFramebuffer() == currentDefault)
378 {
379 mState.setDrawFramebufferBinding(nullptr);
380 }
381 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400382 }
383
Corentin Wallez51706ea2015-08-07 14:39:22 -0400384 mCurrentSurface->setIsCurrent(false);
385 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400386}
387
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000388// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389void Context::markContextLost()
390{
391 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
392 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
393 mContextLost = true;
394}
395
396bool Context::isContextLost()
397{
398 return mContextLost;
399}
400
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401GLuint Context::createBuffer()
402{
403 return mResourceManager->createBuffer();
404}
405
406GLuint Context::createProgram()
407{
408 return mResourceManager->createProgram();
409}
410
411GLuint Context::createShader(GLenum type)
412{
Jamie Madill006cbc52015-09-23 16:47:54 -0400413 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000414}
415
416GLuint Context::createTexture()
417{
418 return mResourceManager->createTexture();
419}
420
421GLuint Context::createRenderbuffer()
422{
423 return mResourceManager->createRenderbuffer();
424}
425
Geoff Lang882033e2014-09-30 11:26:07 -0400426GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400427{
428 GLuint handle = mResourceManager->createFenceSync();
429
Cooper Partind8e62a32015-01-29 15:21:25 -0800430 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400431}
432
Jamie Madill57a89722013-07-02 11:57:03 -0400433GLuint Context::createVertexArray()
434{
Geoff Lang36167ab2015-12-07 10:27:14 -0500435 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
436 mVertexArrayMap[vertexArray] = nullptr;
437 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400438}
439
Jamie Madilldc356042013-07-19 16:36:57 -0400440GLuint Context::createSampler()
441{
442 return mResourceManager->createSampler();
443}
444
Geoff Langc8058452014-02-03 12:04:11 -0500445GLuint Context::createTransformFeedback()
446{
Geoff Lang36167ab2015-12-07 10:27:14 -0500447 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
448 mTransformFeedbackMap[transformFeedback] = nullptr;
449 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500450}
451
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000452// Returns an unused framebuffer name
453GLuint Context::createFramebuffer()
454{
455 GLuint handle = mFramebufferHandleAllocator.allocate();
456
457 mFramebufferMap[handle] = NULL;
458
459 return handle;
460}
461
Jamie Madill33dc8432013-07-26 11:55:05 -0400462GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463{
Jamie Madill33dc8432013-07-26 11:55:05 -0400464 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700466 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000467
468 return handle;
469}
470
471// Returns an unused query name
472GLuint Context::createQuery()
473{
474 GLuint handle = mQueryHandleAllocator.allocate();
475
476 mQueryMap[handle] = NULL;
477
478 return handle;
479}
480
481void Context::deleteBuffer(GLuint buffer)
482{
483 if (mResourceManager->getBuffer(buffer))
484 {
485 detachBuffer(buffer);
486 }
Jamie Madill893ab082014-05-16 16:56:10 -0400487
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488 mResourceManager->deleteBuffer(buffer);
489}
490
491void Context::deleteShader(GLuint shader)
492{
493 mResourceManager->deleteShader(shader);
494}
495
496void Context::deleteProgram(GLuint program)
497{
498 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000499}
500
501void Context::deleteTexture(GLuint texture)
502{
503 if (mResourceManager->getTexture(texture))
504 {
505 detachTexture(texture);
506 }
507
508 mResourceManager->deleteTexture(texture);
509}
510
511void Context::deleteRenderbuffer(GLuint renderbuffer)
512{
513 if (mResourceManager->getRenderbuffer(renderbuffer))
514 {
515 detachRenderbuffer(renderbuffer);
516 }
Jamie Madill893ab082014-05-16 16:56:10 -0400517
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000518 mResourceManager->deleteRenderbuffer(renderbuffer);
519}
520
Jamie Madillcd055f82013-07-26 11:55:15 -0400521void Context::deleteFenceSync(GLsync fenceSync)
522{
523 // The spec specifies the underlying Fence object is not deleted until all current
524 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
525 // and since our API is currently designed for being called from a single thread, we can delete
526 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700527 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400528}
529
Jamie Madill57a89722013-07-02 11:57:03 -0400530void Context::deleteVertexArray(GLuint vertexArray)
531{
Geoff Lang36167ab2015-12-07 10:27:14 -0500532 auto iter = mVertexArrayMap.find(vertexArray);
533 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000534 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500535 VertexArray *vertexArrayObject = iter->second;
536 if (vertexArrayObject != nullptr)
537 {
538 detachVertexArray(vertexArray);
539 delete vertexArrayObject;
540 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000541
Geoff Lang36167ab2015-12-07 10:27:14 -0500542 mVertexArrayMap.erase(iter);
543 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400544 }
545}
546
Jamie Madilldc356042013-07-19 16:36:57 -0400547void Context::deleteSampler(GLuint sampler)
548{
549 if (mResourceManager->getSampler(sampler))
550 {
551 detachSampler(sampler);
552 }
553
554 mResourceManager->deleteSampler(sampler);
555}
556
Geoff Langc8058452014-02-03 12:04:11 -0500557void Context::deleteTransformFeedback(GLuint transformFeedback)
558{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500559 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500560 if (iter != mTransformFeedbackMap.end())
561 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500562 TransformFeedback *transformFeedbackObject = iter->second;
563 if (transformFeedbackObject != nullptr)
564 {
565 detachTransformFeedback(transformFeedback);
566 transformFeedbackObject->release();
567 }
568
Geoff Lang50b3fe82015-12-08 14:49:12 +0000569 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500570 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500571 }
572}
573
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000574void Context::deleteFramebuffer(GLuint framebuffer)
575{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500576 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000577
578 if (framebufferObject != mFramebufferMap.end())
579 {
580 detachFramebuffer(framebuffer);
581
582 mFramebufferHandleAllocator.release(framebufferObject->first);
583 delete framebufferObject->second;
584 mFramebufferMap.erase(framebufferObject);
585 }
586}
587
Jamie Madill33dc8432013-07-26 11:55:05 -0400588void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500590 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591
Jamie Madill33dc8432013-07-26 11:55:05 -0400592 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400594 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400596 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597 }
598}
599
600void Context::deleteQuery(GLuint query)
601{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500602 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603 if (queryObject != mQueryMap.end())
604 {
605 mQueryHandleAllocator.release(queryObject->first);
606 if (queryObject->second)
607 {
608 queryObject->second->release();
609 }
610 mQueryMap.erase(queryObject);
611 }
612}
613
Geoff Lang70d0f492015-12-10 17:45:46 -0500614Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000615{
616 return mResourceManager->getBuffer(handle);
617}
618
Geoff Lang48dcae72014-02-05 16:28:24 -0500619Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000620{
621 return mResourceManager->getShader(handle);
622}
623
Geoff Lang48dcae72014-02-05 16:28:24 -0500624Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000625{
626 return mResourceManager->getProgram(handle);
627}
628
Jamie Madill570f7c82014-07-03 10:38:54 -0400629Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000630{
631 return mResourceManager->getTexture(handle);
632}
633
Geoff Lang70d0f492015-12-10 17:45:46 -0500634Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635{
636 return mResourceManager->getRenderbuffer(handle);
637}
638
Jamie Madillcd055f82013-07-26 11:55:15 -0400639FenceSync *Context::getFenceSync(GLsync handle) const
640{
Minmin Gong794e0002015-04-07 18:31:54 -0700641 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400642}
643
Jamie Madill57a89722013-07-02 11:57:03 -0400644VertexArray *Context::getVertexArray(GLuint handle) const
645{
646 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500647 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400648}
649
Jamie Madilldc356042013-07-19 16:36:57 -0400650Sampler *Context::getSampler(GLuint handle) const
651{
652 return mResourceManager->getSampler(handle);
653}
654
Geoff Langc8058452014-02-03 12:04:11 -0500655TransformFeedback *Context::getTransformFeedback(GLuint handle) const
656{
Geoff Lang36167ab2015-12-07 10:27:14 -0500657 auto iter = mTransformFeedbackMap.find(handle);
658 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500659}
660
Geoff Lang70d0f492015-12-10 17:45:46 -0500661LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
662{
663 switch (identifier)
664 {
665 case GL_BUFFER:
666 return getBuffer(name);
667 case GL_SHADER:
668 return getShader(name);
669 case GL_PROGRAM:
670 return getProgram(name);
671 case GL_VERTEX_ARRAY:
672 return getVertexArray(name);
673 case GL_QUERY:
674 return getQuery(name);
675 case GL_TRANSFORM_FEEDBACK:
676 return getTransformFeedback(name);
677 case GL_SAMPLER:
678 return getSampler(name);
679 case GL_TEXTURE:
680 return getTexture(name);
681 case GL_RENDERBUFFER:
682 return getRenderbuffer(name);
683 case GL_FRAMEBUFFER:
684 return getFramebuffer(name);
685 default:
686 UNREACHABLE();
687 return nullptr;
688 }
689}
690
691LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
692{
693 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
694}
695
Jamie Madilldc356042013-07-19 16:36:57 -0400696bool Context::isSampler(GLuint samplerName) const
697{
698 return mResourceManager->isSampler(samplerName);
699}
700
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500701void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000702{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500703 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
704 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000705}
706
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500707void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
710 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000711}
712
Jamie Madilldedd7b92014-11-05 16:30:36 -0500713void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500715 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000716
Jamie Madilldedd7b92014-11-05 16:30:36 -0500717 if (handle == 0)
718 {
719 texture = mZeroTextures[target].get();
720 }
721 else
722 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500723 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500724 }
725
726 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500727 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000728}
729
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500730void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000731{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500732 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
733 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000734}
735
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500736void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000737{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500738 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
739 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740}
741
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500742void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000743{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500744 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
745 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000746}
747
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500748void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400749{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500750 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
751 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400752}
753
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500754void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400755{
Geoff Lang76b10c92014-09-05 16:28:14 -0400756 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500757 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
758 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400759}
760
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500761void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000762{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500763 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
764 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000765}
766
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500767void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
768 GLuint index,
769 GLintptr offset,
770 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000771{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500772 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
773 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000774}
775
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500776void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000777{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500778 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
779 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000780}
781
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500782void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
783 GLuint index,
784 GLintptr offset,
785 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000786{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500787 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
788 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000789}
790
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500791void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000792{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500793 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
794 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000795}
796
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000798{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
800 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000801}
802
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000804{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500805 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
806 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000807}
808
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500809void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000810{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500811 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
812 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000813}
814
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815void Context::useProgram(GLuint program)
816{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500817 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000818}
819
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500820void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500821{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500822 TransformFeedback *transformFeedback =
823 checkTransformFeedbackAllocation(transformFeedbackHandle);
824 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500825}
826
Geoff Lang5aad9672014-09-08 11:10:42 -0400827Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400830 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831
Geoff Lang5aad9672014-09-08 11:10:42 -0400832 // begin query
833 Error error = queryObject->begin();
834 if (error.isError())
835 {
836 return error;
837 }
838
839 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400840 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000841
Geoff Lang5aad9672014-09-08 11:10:42 -0400842 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843}
844
Geoff Lang5aad9672014-09-08 11:10:42 -0400845Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000846{
Shannon Woods53a94a82014-06-24 15:20:36 -0400847 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400848 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849
Geoff Lang5aad9672014-09-08 11:10:42 -0400850 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851
Geoff Lang5aad9672014-09-08 11:10:42 -0400852 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400853 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400854
855 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000856}
857
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500858Error Context::queryCounter(GLuint id, GLenum target)
859{
860 ASSERT(target == GL_TIMESTAMP_EXT);
861
862 Query *queryObject = getQuery(id, true, target);
863 ASSERT(queryObject);
864
865 return queryObject->queryCounter();
866}
867
868void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
869{
870 switch (pname)
871 {
872 case GL_CURRENT_QUERY_EXT:
873 params[0] = getState().getActiveQueryId(target);
874 break;
875 case GL_QUERY_COUNTER_BITS_EXT:
876 switch (target)
877 {
878 case GL_TIME_ELAPSED_EXT:
879 params[0] = getExtensions().queryCounterBitsTimeElapsed;
880 break;
881 case GL_TIMESTAMP_EXT:
882 params[0] = getExtensions().queryCounterBitsTimestamp;
883 break;
884 default:
885 UNREACHABLE();
886 params[0] = 0;
887 break;
888 }
889 break;
890 default:
891 UNREACHABLE();
892 return;
893 }
894}
895
896Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
897{
898 return GetQueryObjectParameter(this, id, pname, params);
899}
900
901Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
902{
903 return GetQueryObjectParameter(this, id, pname, params);
904}
905
906Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
907{
908 return GetQueryObjectParameter(this, id, pname, params);
909}
910
911Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
912{
913 return GetQueryObjectParameter(this, id, pname, params);
914}
915
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500916Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000917{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500918 auto framebufferIt = mFramebufferMap.find(handle);
919 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000920}
921
Jamie Madill33dc8432013-07-26 11:55:05 -0400922FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500924 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925
Jamie Madill33dc8432013-07-26 11:55:05 -0400926 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000927 {
928 return NULL;
929 }
930 else
931 {
932 return fence->second;
933 }
934}
935
936Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
937{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500938 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000939
940 if (query == mQueryMap.end())
941 {
942 return NULL;
943 }
944 else
945 {
946 if (!query->second && create)
947 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700948 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949 query->second->addRef();
950 }
951 return query->second;
952 }
953}
954
Geoff Lang70d0f492015-12-10 17:45:46 -0500955Query *Context::getQuery(GLuint handle) const
956{
957 auto iter = mQueryMap.find(handle);
958 return (iter != mQueryMap.end()) ? iter->second : nullptr;
959}
960
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500961Texture *Context::getTargetTexture(GLenum target) const
962{
Ian Ewellbda75592016-04-18 17:25:54 -0400963 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500964 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000965}
966
Geoff Lang76b10c92014-09-05 16:28:14 -0400967Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500969 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970}
971
Geoff Lang492a7e42014-11-05 13:27:06 -0500972Compiler *Context::getCompiler() const
973{
974 return mCompiler;
975}
976
Jamie Madill893ab082014-05-16 16:56:10 -0400977void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978{
979 switch (pname)
980 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000981 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000982 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400984 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400985 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill893ab082014-05-16 16:56:10 -0400989void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990{
Shannon Woods53a94a82014-06-24 15:20:36 -0400991 // Queries about context capabilities and maximums are answered by Context.
992 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993 switch (pname)
994 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400996 params[0] = mCaps.minAliasedLineWidth;
997 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000998 break;
999 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001000 params[0] = mCaps.minAliasedPointSize;
1001 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001002 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001003 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001004 ASSERT(mExtensions.textureFilterAnisotropic);
1005 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001006 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001007 case GL_MAX_TEXTURE_LOD_BIAS:
1008 *params = mCaps.maxLODBias;
1009 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001011 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001012 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001013 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001014}
1015
Jamie Madill893ab082014-05-16 16:56:10 -04001016void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001017{
Shannon Woods53a94a82014-06-24 15:20:36 -04001018 // Queries about context capabilities and maximums are answered by Context.
1019 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001020
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001021 switch (pname)
1022 {
Geoff Lang301d1612014-07-09 10:34:37 -04001023 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1024 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1025 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001026 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1027 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1028 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001029 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1030 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1031 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001032 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001033 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1034 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1035 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001036 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001037 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001038 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1039 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1040 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1041 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001042 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1043 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001044 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1045 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001046 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001047 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1048 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1049 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1050 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001051 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1052 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001053 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1054 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001055 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1056 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1057 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001058 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1059 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1060 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001061 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001062 case GL_MAX_VIEWPORT_DIMS:
1063 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001064 params[0] = mCaps.maxViewportWidth;
1065 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001066 }
1067 break;
1068 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001069 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1072 *params = mResetStrategy;
1073 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001074 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001075 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001077 case GL_SHADER_BINARY_FORMATS:
1078 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1079 break;
1080 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001081 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001082 break;
1083 case GL_PROGRAM_BINARY_FORMATS:
1084 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001086 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001087 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001088 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001089
1090 // GL_KHR_debug
1091 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1092 *params = mExtensions.maxDebugMessageLength;
1093 break;
1094 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1095 *params = mExtensions.maxDebugLoggedMessages;
1096 break;
1097 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1098 *params = mExtensions.maxDebugGroupStackDepth;
1099 break;
1100 case GL_MAX_LABEL_LENGTH:
1101 *params = mExtensions.maxLabelLength;
1102 break;
1103
Ian Ewell53f59f42016-01-28 17:36:55 -05001104 // GL_EXT_disjoint_timer_query
1105 case GL_GPU_DISJOINT_EXT:
1106 *params = mRenderer->getGPUDisjoint();
1107 break;
1108
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001109 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001110 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001111 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001113}
1114
Jamie Madill893ab082014-05-16 16:56:10 -04001115void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001116{
Shannon Woods53a94a82014-06-24 15:20:36 -04001117 // Queries about context capabilities and maximums are answered by Context.
1118 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001119 switch (pname)
1120 {
1121 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001122 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001123 break;
1124 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001125 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001126 break;
1127 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001128 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001129 break;
1130 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001131 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001132 break;
1133 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001134 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001136
1137 // GL_EXT_disjoint_timer_query
1138 case GL_TIMESTAMP_EXT:
1139 *params = mRenderer->getTimestamp();
1140 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001141 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001142 UNREACHABLE();
1143 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001144 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001145}
1146
Geoff Lang70d0f492015-12-10 17:45:46 -05001147void Context::getPointerv(GLenum pname, void **params) const
1148{
1149 mState.getPointerv(pname, params);
1150}
1151
Shannon Woods1b2fb852013-08-19 14:28:48 -04001152bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1153{
Shannon Woods53a94a82014-06-24 15:20:36 -04001154 // Queries about context capabilities and maximums are answered by Context.
1155 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001156 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001157 // mere passthrough.
1158 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001159}
1160
1161bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1162{
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 // Queries about context capabilities and maximums are answered by Context.
1164 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001165 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001166 // mere passthrough.
1167 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001168}
1169
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1171{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001172 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1173 {
1174 *type = GL_INT;
1175 *numParams = 1;
1176 return true;
1177 }
1178
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001179 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1180 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1181 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001182 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001183 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1184 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1185 // application.
1186 switch (pname)
1187 {
1188 case GL_COMPRESSED_TEXTURE_FORMATS:
1189 {
1190 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001191 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001192 }
1193 return true;
1194 case GL_PROGRAM_BINARY_FORMATS_OES:
1195 {
1196 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001197 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001198 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001199 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001200 case GL_SHADER_BINARY_FORMATS:
1201 {
1202 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001203 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001205 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001206
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001207 case GL_MAX_VERTEX_ATTRIBS:
1208 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1209 case GL_MAX_VARYING_VECTORS:
1210 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1211 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1212 case GL_MAX_TEXTURE_IMAGE_UNITS:
1213 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1214 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001215 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001216 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217 case GL_NUM_SHADER_BINARY_FORMATS:
1218 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1219 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001220 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1221 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1222 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 case GL_RENDERBUFFER_BINDING:
1224 case GL_CURRENT_PROGRAM:
1225 case GL_PACK_ALIGNMENT:
1226 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1227 case GL_UNPACK_ALIGNMENT:
1228 case GL_GENERATE_MIPMAP_HINT:
1229 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1230 case GL_RED_BITS:
1231 case GL_GREEN_BITS:
1232 case GL_BLUE_BITS:
1233 case GL_ALPHA_BITS:
1234 case GL_DEPTH_BITS:
1235 case GL_STENCIL_BITS:
1236 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1237 case GL_CULL_FACE_MODE:
1238 case GL_FRONT_FACE:
1239 case GL_ACTIVE_TEXTURE:
1240 case GL_STENCIL_FUNC:
1241 case GL_STENCIL_VALUE_MASK:
1242 case GL_STENCIL_REF:
1243 case GL_STENCIL_FAIL:
1244 case GL_STENCIL_PASS_DEPTH_FAIL:
1245 case GL_STENCIL_PASS_DEPTH_PASS:
1246 case GL_STENCIL_BACK_FUNC:
1247 case GL_STENCIL_BACK_VALUE_MASK:
1248 case GL_STENCIL_BACK_REF:
1249 case GL_STENCIL_BACK_FAIL:
1250 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1251 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1252 case GL_DEPTH_FUNC:
1253 case GL_BLEND_SRC_RGB:
1254 case GL_BLEND_SRC_ALPHA:
1255 case GL_BLEND_DST_RGB:
1256 case GL_BLEND_DST_ALPHA:
1257 case GL_BLEND_EQUATION_RGB:
1258 case GL_BLEND_EQUATION_ALPHA:
1259 case GL_STENCIL_WRITEMASK:
1260 case GL_STENCIL_BACK_WRITEMASK:
1261 case GL_STENCIL_CLEAR_VALUE:
1262 case GL_SUBPIXEL_BITS:
1263 case GL_MAX_TEXTURE_SIZE:
1264 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1265 case GL_SAMPLE_BUFFERS:
1266 case GL_SAMPLES:
1267 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1268 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1269 case GL_TEXTURE_BINDING_2D:
1270 case GL_TEXTURE_BINDING_CUBE_MAP:
1271 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1272 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 {
1274 *type = GL_INT;
1275 *numParams = 1;
1276 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001277 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001278 case GL_MAX_SAMPLES_ANGLE:
1279 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001280 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001281 {
1282 *type = GL_INT;
1283 *numParams = 1;
1284 }
1285 else
1286 {
1287 return false;
1288 }
1289 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001290 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001291 case GL_MAX_VIEWPORT_DIMS:
1292 {
1293 *type = GL_INT;
1294 *numParams = 2;
1295 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001296 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297 case GL_VIEWPORT:
1298 case GL_SCISSOR_BOX:
1299 {
1300 *type = GL_INT;
1301 *numParams = 4;
1302 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001303 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001304 case GL_SHADER_COMPILER:
1305 case GL_SAMPLE_COVERAGE_INVERT:
1306 case GL_DEPTH_WRITEMASK:
1307 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1308 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1309 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1310 case GL_SAMPLE_COVERAGE:
1311 case GL_SCISSOR_TEST:
1312 case GL_STENCIL_TEST:
1313 case GL_DEPTH_TEST:
1314 case GL_BLEND:
1315 case GL_DITHER:
1316 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1317 {
1318 *type = GL_BOOL;
1319 *numParams = 1;
1320 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001321 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 case GL_COLOR_WRITEMASK:
1323 {
1324 *type = GL_BOOL;
1325 *numParams = 4;
1326 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001327 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_POLYGON_OFFSET_FACTOR:
1329 case GL_POLYGON_OFFSET_UNITS:
1330 case GL_SAMPLE_COVERAGE_VALUE:
1331 case GL_DEPTH_CLEAR_VALUE:
1332 case GL_LINE_WIDTH:
1333 {
1334 *type = GL_FLOAT;
1335 *numParams = 1;
1336 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001337 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001338 case GL_ALIASED_LINE_WIDTH_RANGE:
1339 case GL_ALIASED_POINT_SIZE_RANGE:
1340 case GL_DEPTH_RANGE:
1341 {
1342 *type = GL_FLOAT;
1343 *numParams = 2;
1344 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001345 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346 case GL_COLOR_CLEAR_VALUE:
1347 case GL_BLEND_COLOR:
1348 {
1349 *type = GL_FLOAT;
1350 *numParams = 4;
1351 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001352 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001353 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001354 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001355 {
1356 return false;
1357 }
1358 *type = GL_FLOAT;
1359 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001360 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001361 case GL_TIMESTAMP_EXT:
1362 if (!mExtensions.disjointTimerQuery)
1363 {
1364 return false;
1365 }
1366 *type = GL_INT_64_ANGLEX;
1367 *numParams = 1;
1368 return true;
1369 case GL_GPU_DISJOINT_EXT:
1370 if (!mExtensions.disjointTimerQuery)
1371 {
1372 return false;
1373 }
1374 *type = GL_INT;
1375 *numParams = 1;
1376 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001377 }
1378
Geoff Lang70d0f492015-12-10 17:45:46 -05001379 if (mExtensions.debug)
1380 {
1381 switch (pname)
1382 {
1383 case GL_DEBUG_LOGGED_MESSAGES:
1384 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1385 case GL_DEBUG_GROUP_STACK_DEPTH:
1386 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1387 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1388 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1389 case GL_MAX_LABEL_LENGTH:
1390 *type = GL_INT;
1391 *numParams = 1;
1392 return true;
1393
1394 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1395 case GL_DEBUG_OUTPUT:
1396 *type = GL_BOOL;
1397 *numParams = 1;
1398 return true;
1399 }
1400 }
1401
Austin Kinrossbc781f32015-10-26 09:27:38 -07001402 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1403 switch (pname)
1404 {
1405 case GL_PACK_ROW_LENGTH:
1406 case GL_PACK_SKIP_ROWS:
1407 case GL_PACK_SKIP_PIXELS:
1408 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1409 {
1410 return false;
1411 }
1412 *type = GL_INT;
1413 *numParams = 1;
1414 return true;
1415 case GL_UNPACK_ROW_LENGTH:
1416 case GL_UNPACK_SKIP_ROWS:
1417 case GL_UNPACK_SKIP_PIXELS:
1418 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1419 {
1420 return false;
1421 }
1422 *type = GL_INT;
1423 *numParams = 1;
1424 return true;
1425 case GL_VERTEX_ARRAY_BINDING:
1426 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1427 {
1428 return false;
1429 }
1430 *type = GL_INT;
1431 *numParams = 1;
1432 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001433 case GL_PIXEL_PACK_BUFFER_BINDING:
1434 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1435 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1436 {
1437 return false;
1438 }
1439 *type = GL_INT;
1440 *numParams = 1;
1441 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001442 }
1443
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001444 if (mClientVersion < 3)
1445 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001446 return false;
1447 }
1448
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001449 // Check for ES3.0+ parameter names
1450 switch (pname)
1451 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001452 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1453 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001454 case GL_UNIFORM_BUFFER_BINDING:
1455 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001456 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001457 case GL_COPY_READ_BUFFER_BINDING:
1458 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001459 case GL_SAMPLER_BINDING:
1460 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001461 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001462 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001463 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001464 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001465 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1466 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1467 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001468 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1469 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001470 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001471 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1472 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001473 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1474 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001475 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001476 case GL_MAJOR_VERSION:
1477 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001478 case GL_MAX_ELEMENTS_INDICES:
1479 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001480 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001481 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001482 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001483 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001484 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001485 {
1486 *type = GL_INT;
1487 *numParams = 1;
1488 }
1489 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001490
1491 case GL_MAX_ELEMENT_INDEX:
1492 case GL_MAX_UNIFORM_BLOCK_SIZE:
1493 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1494 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1495 case GL_MAX_SERVER_WAIT_TIMEOUT:
1496 {
1497 *type = GL_INT_64_ANGLEX;
1498 *numParams = 1;
1499 }
1500 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001501
1502 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001503 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001504 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001505 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001506 {
1507 *type = GL_BOOL;
1508 *numParams = 1;
1509 }
1510 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001511
1512 case GL_MAX_TEXTURE_LOD_BIAS:
1513 {
1514 *type = GL_FLOAT;
1515 *numParams = 1;
1516 }
1517 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001518 }
1519
1520 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001521}
1522
Shannon Woods1b2fb852013-08-19 14:28:48 -04001523bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1524{
1525 if (mClientVersion < 3)
1526 {
1527 return false;
1528 }
1529
1530 switch (target)
1531 {
1532 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1533 case GL_UNIFORM_BUFFER_BINDING:
1534 {
1535 *type = GL_INT;
1536 *numParams = 1;
1537 }
1538 return true;
1539 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1540 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1541 case GL_UNIFORM_BUFFER_START:
1542 case GL_UNIFORM_BUFFER_SIZE:
1543 {
1544 *type = GL_INT_64_ANGLEX;
1545 *numParams = 1;
1546 }
1547 }
1548
1549 return false;
1550}
1551
Geoff Langf6db0982015-08-25 13:04:00 -04001552Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001553{
Jamie Madill1b94d432015-08-07 13:23:23 -04001554 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001555 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001556 if (error.isError())
1557 {
1558 return error;
1559 }
1560
Geoff Langf6db0982015-08-25 13:04:00 -04001561 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001562
1563 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001564}
1565
Geoff Langf6db0982015-08-25 13:04:00 -04001566Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1567{
1568 syncRendererState();
1569 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1570 if (error.isError())
1571 {
1572 return error;
1573 }
1574
1575 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1576
1577 return Error(GL_NO_ERROR);
1578}
1579
1580Error Context::drawElements(GLenum mode,
1581 GLsizei count,
1582 GLenum type,
1583 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001584 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001585{
Jamie Madill1b94d432015-08-07 13:23:23 -04001586 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001587 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1588}
1589
1590Error Context::drawElementsInstanced(GLenum mode,
1591 GLsizei count,
1592 GLenum type,
1593 const GLvoid *indices,
1594 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001595 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001596{
1597 syncRendererState();
1598 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1599 indexRange);
1600}
1601
1602Error Context::drawRangeElements(GLenum mode,
1603 GLuint start,
1604 GLuint end,
1605 GLsizei count,
1606 GLenum type,
1607 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001608 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001609{
1610 syncRendererState();
1611 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1612 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Geoff Lang129753a2015-01-09 16:52:09 -05001615Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001616{
Geoff Lang129753a2015-01-09 16:52:09 -05001617 return mRenderer->flush();
1618}
1619
1620Error Context::finish()
1621{
1622 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001623}
1624
Austin Kinross6ee1e782015-05-29 17:05:37 -07001625void Context::insertEventMarker(GLsizei length, const char *marker)
1626{
1627 ASSERT(mRenderer);
1628 mRenderer->insertEventMarker(length, marker);
1629}
1630
1631void Context::pushGroupMarker(GLsizei length, const char *marker)
1632{
1633 ASSERT(mRenderer);
1634 mRenderer->pushGroupMarker(length, marker);
1635}
1636
1637void Context::popGroupMarker()
1638{
1639 ASSERT(mRenderer);
1640 mRenderer->popGroupMarker();
1641}
1642
Geoff Langd8605522016-04-13 10:19:12 -04001643void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1644{
1645 Program *programObject = getProgram(program);
1646 ASSERT(programObject);
1647
1648 programObject->bindUniformLocation(location, name);
1649}
1650
Geoff Langda5777c2014-07-11 09:52:58 -04001651void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001652{
Geoff Langda5777c2014-07-11 09:52:58 -04001653 if (error.isError())
1654 {
1655 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001656
1657 if (!error.getMessage().empty())
1658 {
1659 auto &debug = mState.getDebug();
1660 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1661 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1662 }
Geoff Langda5777c2014-07-11 09:52:58 -04001663 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001664}
1665
1666// Get one of the recorded errors and clear its flag, if any.
1667// [OpenGL ES 2.0.24] section 2.5 page 13.
1668GLenum Context::getError()
1669{
Geoff Langda5777c2014-07-11 09:52:58 -04001670 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671 {
Geoff Langda5777c2014-07-11 09:52:58 -04001672 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673 }
Geoff Langda5777c2014-07-11 09:52:58 -04001674 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001675 {
Geoff Langda5777c2014-07-11 09:52:58 -04001676 GLenum error = *mErrors.begin();
1677 mErrors.erase(mErrors.begin());
1678 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001679 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001680}
1681
1682GLenum Context::getResetStatus()
1683{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001684 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001685 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001687 // mResetStatus will be set by the markContextLost callback
1688 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001689 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001690 {
1691 mRenderer->notifyDeviceLost();
1692 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693 }
1694
1695 GLenum status = mResetStatus;
1696
1697 if (mResetStatus != GL_NO_ERROR)
1698 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001699 ASSERT(mContextLost);
1700
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001701 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001702 {
1703 mResetStatus = GL_NO_ERROR;
1704 }
1705 }
Jamie Madill893ab082014-05-16 16:56:10 -04001706
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001707 return status;
1708}
1709
1710bool Context::isResetNotificationEnabled()
1711{
1712 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1713}
1714
Corentin Walleze3b10e82015-05-20 11:06:25 -04001715const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001716{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001717 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001718}
1719
1720EGLenum Context::getClientType() const
1721{
1722 return mClientType;
1723}
1724
1725EGLenum Context::getRenderBuffer() const
1726{
Corentin Wallez37c39792015-08-20 14:19:46 -04001727 auto framebufferIt = mFramebufferMap.find(0);
1728 if (framebufferIt != mFramebufferMap.end())
1729 {
1730 const Framebuffer *framebuffer = framebufferIt->second;
1731 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1732
1733 ASSERT(backAttachment != nullptr);
1734 return backAttachment->getSurface()->getRenderBuffer();
1735 }
1736 else
1737 {
1738 return EGL_NONE;
1739 }
Régis Fénéon83107972015-02-05 12:57:44 +01001740}
1741
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001742VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001743{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001744 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001745 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1746 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001747 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001748 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1749 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001750 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001751
1752 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001753}
1754
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001755TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001756{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001757 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001758 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1759 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001760 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001761 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1762 transformFeedback->addRef();
1763 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001764 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001765
1766 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001767}
1768
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001769Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1770{
1771 // Can be called from Bind without a prior call to Gen.
1772 auto framebufferIt = mFramebufferMap.find(framebuffer);
1773 bool neverCreated = framebufferIt == mFramebufferMap.end();
1774 if (neverCreated || framebufferIt->second == nullptr)
1775 {
1776 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1777 if (neverCreated)
1778 {
1779 mFramebufferHandleAllocator.reserve(framebuffer);
1780 mFramebufferMap[framebuffer] = newFBO;
1781 return newFBO;
1782 }
1783
1784 framebufferIt->second = newFBO;
1785 }
1786
1787 return framebufferIt->second;
1788}
1789
Geoff Lang36167ab2015-12-07 10:27:14 -05001790bool Context::isVertexArrayGenerated(GLuint vertexArray)
1791{
1792 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1793}
1794
1795bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1796{
1797 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1798}
1799
Shannon Woods53a94a82014-06-24 15:20:36 -04001800void Context::detachTexture(GLuint texture)
1801{
1802 // Simple pass-through to State's detachTexture method, as textures do not require
1803 // allocation map management either here or in the resource manager at detach time.
1804 // Zero textures are held by the Context, and we don't attempt to request them from
1805 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001806 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001807}
1808
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001809void Context::detachBuffer(GLuint buffer)
1810{
Yuly Novikov5807a532015-12-03 13:01:22 -05001811 // Simple pass-through to State's detachBuffer method, since
1812 // only buffer attachments to container objects that are bound to the current context
1813 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001814
Yuly Novikov5807a532015-12-03 13:01:22 -05001815 // [OpenGL ES 3.2] section 5.1.2 page 45:
1816 // Attachments to unbound container objects, such as
1817 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1818 // are not affected and continue to act as references on the deleted object
1819 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001820}
1821
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001822void Context::detachFramebuffer(GLuint framebuffer)
1823{
Shannon Woods53a94a82014-06-24 15:20:36 -04001824 // Framebuffer detachment is handled by Context, because 0 is a valid
1825 // Framebuffer object, and a pointer to it must be passed from Context
1826 // to State at binding time.
1827
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001828 // [OpenGL ES 2.0.24] section 4.4 page 107:
1829 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1830 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1831
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001832 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833 {
1834 bindReadFramebuffer(0);
1835 }
1836
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001837 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001838 {
1839 bindDrawFramebuffer(0);
1840 }
1841}
1842
1843void Context::detachRenderbuffer(GLuint renderbuffer)
1844{
Shannon Woods53a94a82014-06-24 15:20:36 -04001845 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001846}
1847
Jamie Madill57a89722013-07-02 11:57:03 -04001848void Context::detachVertexArray(GLuint vertexArray)
1849{
Jamie Madill77a72f62015-04-14 11:18:32 -04001850 // Vertex array detachment is handled by Context, because 0 is a valid
1851 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001852 // binding time.
1853
Jamie Madill57a89722013-07-02 11:57:03 -04001854 // [OpenGL ES 3.0.2] section 2.10 page 43:
1855 // If a vertex array object that is currently bound is deleted, the binding
1856 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001857 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001858 {
1859 bindVertexArray(0);
1860 }
1861}
1862
Geoff Langc8058452014-02-03 12:04:11 -05001863void Context::detachTransformFeedback(GLuint transformFeedback)
1864{
Shannon Woods53a94a82014-06-24 15:20:36 -04001865 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001866}
1867
Jamie Madilldc356042013-07-19 16:36:57 -04001868void Context::detachSampler(GLuint sampler)
1869{
Shannon Woods53a94a82014-06-24 15:20:36 -04001870 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001871}
1872
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001873void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1874{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001875 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001876}
1877
Jamie Madille29d1672013-07-19 16:36:57 -04001878void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1879{
1880 mResourceManager->checkSamplerAllocation(sampler);
1881
1882 Sampler *samplerObject = getSampler(sampler);
1883 ASSERT(samplerObject);
1884
Geoff Lang69cce582015-09-17 13:20:36 -04001885 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001886 switch (pname)
1887 {
Geoff Lang69cce582015-09-17 13:20:36 -04001888 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1889 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1890 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1891 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1892 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1893 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1894 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1895 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1896 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1897 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1898 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001899 }
Geoff Lang69cce582015-09-17 13:20:36 -04001900 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001901}
1902
1903void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1904{
1905 mResourceManager->checkSamplerAllocation(sampler);
1906
1907 Sampler *samplerObject = getSampler(sampler);
1908 ASSERT(samplerObject);
1909
Geoff Lang69cce582015-09-17 13:20:36 -04001910 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001911 switch (pname)
1912 {
Geoff Lang69cce582015-09-17 13:20:36 -04001913 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1914 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1915 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1916 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1917 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1918 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1919 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1920 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1921 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1922 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1923 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001924 }
Geoff Lang69cce582015-09-17 13:20:36 -04001925 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001926}
1927
Jamie Madill9675b802013-07-19 16:36:59 -04001928GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1929{
1930 mResourceManager->checkSamplerAllocation(sampler);
1931
1932 Sampler *samplerObject = getSampler(sampler);
1933 ASSERT(samplerObject);
1934
Geoff Lang69cce582015-09-17 13:20:36 -04001935 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001936 switch (pname)
1937 {
Geoff Lang69cce582015-09-17 13:20:36 -04001938 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1939 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1940 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1941 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1942 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1943 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001944 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1945 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001946 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1947 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1948 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001949 }
Geoff Lang69cce582015-09-17 13:20:36 -04001950 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001951}
1952
1953GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1954{
1955 mResourceManager->checkSamplerAllocation(sampler);
1956
1957 Sampler *samplerObject = getSampler(sampler);
1958 ASSERT(samplerObject);
1959
Geoff Lang69cce582015-09-17 13:20:36 -04001960 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001961 switch (pname)
1962 {
Geoff Lang69cce582015-09-17 13:20:36 -04001963 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1964 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1965 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1966 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1967 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1968 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1969 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1970 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1971 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1972 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1973 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001974 }
Geoff Lang69cce582015-09-17 13:20:36 -04001975 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001976}
1977
Olli Etuahof0fee072016-03-30 15:11:58 +03001978void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1979{
1980 gl::Program *programObject = getProgram(program);
1981 ASSERT(programObject != nullptr);
1982
1983 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1984 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1985}
1986
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001987void Context::initRendererString()
1988{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001989 std::ostringstream rendererString;
1990 rendererString << "ANGLE (";
1991 rendererString << mRenderer->getRendererDescription();
1992 rendererString << ")";
1993
Geoff Langcec35902014-04-16 10:52:36 -04001994 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001995}
1996
Geoff Langc0b9ef42014-07-02 10:02:37 -04001997const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001999 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002000}
2001
Geoff Langcec35902014-04-16 10:52:36 -04002002void Context::initExtensionStrings()
2003{
Geoff Lang493daf52014-07-03 13:38:44 -04002004 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002005
Geoff Langc0b9ef42014-07-02 10:02:37 -04002006 std::ostringstream combinedStringStream;
2007 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2008 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002009}
2010
Geoff Langc0b9ef42014-07-02 10:02:37 -04002011const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002012{
2013 return mExtensionString;
2014}
2015
Geoff Langc0b9ef42014-07-02 10:02:37 -04002016const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002017{
2018 return mExtensionStrings[idx];
2019}
2020
2021size_t Context::getExtensionStringCount() const
2022{
2023 return mExtensionStrings.size();
2024}
2025
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002026void Context::beginTransformFeedback(GLenum primitiveMode)
2027{
2028 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2029 ASSERT(transformFeedback != nullptr);
2030 ASSERT(!transformFeedback->isPaused());
2031
2032 transformFeedback->begin(primitiveMode, getState().getProgram());
2033}
2034
2035bool Context::hasActiveTransformFeedback(GLuint program) const
2036{
2037 for (auto pair : mTransformFeedbackMap)
2038 {
2039 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2040 {
2041 return true;
2042 }
2043 }
2044 return false;
2045}
2046
Geoff Lang493daf52014-07-03 13:38:44 -04002047void Context::initCaps(GLuint clientVersion)
2048{
2049 mCaps = mRenderer->getRendererCaps();
2050
2051 mExtensions = mRenderer->getRendererExtensions();
2052
Austin Kinross02df7962015-07-01 10:03:42 -07002053 mLimitations = mRenderer->getRendererLimitations();
2054
Geoff Lang493daf52014-07-03 13:38:44 -04002055 if (clientVersion < 3)
2056 {
2057 // Disable ES3+ extensions
2058 mExtensions.colorBufferFloat = false;
2059 }
2060
2061 if (clientVersion > 2)
2062 {
2063 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2064 //mExtensions.sRGB = false;
2065 }
2066
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 // Explicitly enable GL_KHR_debug
2068 mExtensions.debug = true;
2069 mExtensions.maxDebugMessageLength = 1024;
2070 mExtensions.maxDebugLoggedMessages = 1024;
2071 mExtensions.maxDebugGroupStackDepth = 1024;
2072 mExtensions.maxLabelLength = 1024;
2073
Geoff Lang301d1612014-07-09 10:34:37 -04002074 // Apply implementation limits
2075 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002076 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2077 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2078
2079 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002080
Geoff Lang900013c2014-07-07 11:32:19 -04002081 mCaps.compressedTextureFormats.clear();
2082
Geoff Lang493daf52014-07-03 13:38:44 -04002083 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2084 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2085 {
2086 GLenum format = i->first;
2087 TextureCaps formatCaps = i->second;
2088
Geoff Lang5d601382014-07-22 15:14:06 -04002089 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002090
Geoff Lang0d8b7242015-09-09 14:56:53 -04002091 // Update the format caps based on the client version and extensions.
2092 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2093 // ES3.
2094 formatCaps.texturable =
2095 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2096 formatCaps.renderable =
2097 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2098 formatCaps.filterable =
2099 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002100
2101 // OpenGL ES does not support multisampling with integer formats
2102 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002103 {
Geoff Langd87878e2014-09-19 15:42:59 -04002104 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002105 }
Geoff Langd87878e2014-09-19 15:42:59 -04002106
2107 if (formatCaps.texturable && formatInfo.compressed)
2108 {
2109 mCaps.compressedTextureFormats.push_back(format);
2110 }
2111
2112 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002113 }
2114}
2115
Jamie Madill1b94d432015-08-07 13:23:23 -04002116void Context::syncRendererState()
2117{
2118 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002119 mRenderer->syncState(mState, dirtyBits);
2120 mState.clearDirtyBits();
2121 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002122}
2123
Jamie Madillad9f24e2016-02-12 09:27:24 -05002124void Context::syncRendererState(const State::DirtyBits &bitMask,
2125 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002126{
2127 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002128 mRenderer->syncState(mState, dirtyBits);
2129 mState.clearDirtyBits(dirtyBits);
2130
Jamie Madillad9f24e2016-02-12 09:27:24 -05002131 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002132}
Jamie Madillc29968b2016-01-20 11:17:23 -05002133
2134void Context::blitFramebuffer(GLint srcX0,
2135 GLint srcY0,
2136 GLint srcX1,
2137 GLint srcY1,
2138 GLint dstX0,
2139 GLint dstY0,
2140 GLint dstX1,
2141 GLint dstY1,
2142 GLbitfield mask,
2143 GLenum filter)
2144{
2145 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2146 ASSERT(readFramebuffer);
2147
2148 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2149 ASSERT(drawFramebuffer);
2150
2151 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2152 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2153
Jamie Madillad9f24e2016-02-12 09:27:24 -05002154 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002155
2156 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2157 if (error.isError())
2158 {
2159 recordError(error);
2160 return;
2161 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002162}
Jamie Madillc29968b2016-01-20 11:17:23 -05002163
2164void Context::clear(GLbitfield mask)
2165{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002166 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002167
2168 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2169 if (error.isError())
2170 {
2171 recordError(error);
2172 }
2173}
2174
2175void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2176{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002177 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002178
2179 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2180 if (error.isError())
2181 {
2182 recordError(error);
2183 }
2184}
2185
2186void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2187{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002188 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002189
2190 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2191 if (error.isError())
2192 {
2193 recordError(error);
2194 }
2195}
2196
2197void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2198{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002199 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002200
2201 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2202 if (error.isError())
2203 {
2204 recordError(error);
2205 }
2206}
2207
2208void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2209{
2210 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2211 ASSERT(framebufferObject);
2212
2213 // If a buffer is not present, the clear has no effect
2214 if (framebufferObject->getDepthbuffer() == nullptr &&
2215 framebufferObject->getStencilbuffer() == nullptr)
2216 {
2217 return;
2218 }
2219
Jamie Madillad9f24e2016-02-12 09:27:24 -05002220 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002221
2222 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2223 if (error.isError())
2224 {
2225 recordError(error);
2226 }
2227}
2228
2229void Context::readPixels(GLint x,
2230 GLint y,
2231 GLsizei width,
2232 GLsizei height,
2233 GLenum format,
2234 GLenum type,
2235 GLvoid *pixels)
2236{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002237 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002238
2239 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2240 ASSERT(framebufferObject);
2241
2242 Rectangle area(x, y, width, height);
2243 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2244 if (error.isError())
2245 {
2246 recordError(error);
2247 }
2248}
2249
2250void Context::copyTexImage2D(GLenum target,
2251 GLint level,
2252 GLenum internalformat,
2253 GLint x,
2254 GLint y,
2255 GLsizei width,
2256 GLsizei height,
2257 GLint border)
2258{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002259 // Only sync the read FBO
2260 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2261
Jamie Madillc29968b2016-01-20 11:17:23 -05002262 Rectangle sourceArea(x, y, width, height);
2263
2264 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2265 Texture *texture =
2266 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2267 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2268 if (error.isError())
2269 {
2270 recordError(error);
2271 }
2272}
2273
2274void Context::copyTexSubImage2D(GLenum target,
2275 GLint level,
2276 GLint xoffset,
2277 GLint yoffset,
2278 GLint x,
2279 GLint y,
2280 GLsizei width,
2281 GLsizei height)
2282{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002283 // Only sync the read FBO
2284 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2285
Jamie Madillc29968b2016-01-20 11:17:23 -05002286 Offset destOffset(xoffset, yoffset, 0);
2287 Rectangle sourceArea(x, y, width, height);
2288
2289 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2290 Texture *texture =
2291 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2292 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2293 if (error.isError())
2294 {
2295 recordError(error);
2296 }
2297}
2298
2299void Context::copyTexSubImage3D(GLenum target,
2300 GLint level,
2301 GLint xoffset,
2302 GLint yoffset,
2303 GLint zoffset,
2304 GLint x,
2305 GLint y,
2306 GLsizei width,
2307 GLsizei height)
2308{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002309 // Only sync the read FBO
2310 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2311
Jamie Madillc29968b2016-01-20 11:17:23 -05002312 Offset destOffset(xoffset, yoffset, zoffset);
2313 Rectangle sourceArea(x, y, width, height);
2314
2315 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2316 Texture *texture = getTargetTexture(target);
2317 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2318 if (error.isError())
2319 {
2320 recordError(error);
2321 }
2322}
2323
2324void Context::framebufferTexture2D(GLenum target,
2325 GLenum attachment,
2326 GLenum textarget,
2327 GLuint texture,
2328 GLint level)
2329{
2330 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2331 ASSERT(framebuffer);
2332
2333 if (texture != 0)
2334 {
2335 Texture *textureObj = getTexture(texture);
2336
2337 ImageIndex index = ImageIndex::MakeInvalid();
2338
2339 if (textarget == GL_TEXTURE_2D)
2340 {
2341 index = ImageIndex::Make2D(level);
2342 }
2343 else
2344 {
2345 ASSERT(IsCubeMapTextureTarget(textarget));
2346 index = ImageIndex::MakeCube(textarget, level);
2347 }
2348
2349 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2350 }
2351 else
2352 {
2353 framebuffer->resetAttachment(attachment);
2354 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002355
2356 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002357}
2358
2359void Context::framebufferRenderbuffer(GLenum target,
2360 GLenum attachment,
2361 GLenum renderbuffertarget,
2362 GLuint renderbuffer)
2363{
2364 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2365 ASSERT(framebuffer);
2366
2367 if (renderbuffer != 0)
2368 {
2369 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2370 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2371 renderbufferObject);
2372 }
2373 else
2374 {
2375 framebuffer->resetAttachment(attachment);
2376 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002377
2378 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002379}
2380
2381void Context::framebufferTextureLayer(GLenum target,
2382 GLenum attachment,
2383 GLuint texture,
2384 GLint level,
2385 GLint layer)
2386{
2387 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2388 ASSERT(framebuffer);
2389
2390 if (texture != 0)
2391 {
2392 Texture *textureObject = getTexture(texture);
2393
2394 ImageIndex index = ImageIndex::MakeInvalid();
2395
2396 if (textureObject->getTarget() == GL_TEXTURE_3D)
2397 {
2398 index = ImageIndex::Make3D(level, layer);
2399 }
2400 else
2401 {
2402 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2403 index = ImageIndex::Make2DArray(level, layer);
2404 }
2405
2406 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2407 }
2408 else
2409 {
2410 framebuffer->resetAttachment(attachment);
2411 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002412
2413 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002414}
2415
2416void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2417{
2418 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2419 ASSERT(framebuffer);
2420 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002421 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002422}
2423
2424void Context::readBuffer(GLenum mode)
2425{
2426 Framebuffer *readFBO = mState.getReadFramebuffer();
2427 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002428 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002429}
2430
2431void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2432{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002433 // Only sync the FBO
2434 mState.syncDirtyObject(target);
2435
Jamie Madillc29968b2016-01-20 11:17:23 -05002436 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2437 ASSERT(framebuffer);
2438
2439 // The specification isn't clear what should be done when the framebuffer isn't complete.
2440 // We leave it up to the framebuffer implementation to decide what to do.
2441 Error error = framebuffer->discard(numAttachments, attachments);
2442 if (error.isError())
2443 {
2444 recordError(error);
2445 }
2446}
2447
2448void Context::invalidateFramebuffer(GLenum target,
2449 GLsizei numAttachments,
2450 const GLenum *attachments)
2451{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002452 // Only sync the FBO
2453 mState.syncDirtyObject(target);
2454
Jamie Madillc29968b2016-01-20 11:17:23 -05002455 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2456 ASSERT(framebuffer);
2457
2458 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2459 {
2460 Error error = framebuffer->invalidate(numAttachments, attachments);
2461 if (error.isError())
2462 {
2463 recordError(error);
2464 return;
2465 }
2466 }
2467}
2468
2469void Context::invalidateSubFramebuffer(GLenum target,
2470 GLsizei numAttachments,
2471 const GLenum *attachments,
2472 GLint x,
2473 GLint y,
2474 GLsizei width,
2475 GLsizei height)
2476{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002477 // Only sync the FBO
2478 mState.syncDirtyObject(target);
2479
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2481 ASSERT(framebuffer);
2482
2483 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2484 {
2485 Rectangle area(x, y, width, height);
2486 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2487 if (error.isError())
2488 {
2489 recordError(error);
2490 return;
2491 }
2492 }
2493}
2494
Jamie Madill73a84962016-02-12 09:27:23 -05002495void Context::texImage2D(GLenum target,
2496 GLint level,
2497 GLint internalformat,
2498 GLsizei width,
2499 GLsizei height,
2500 GLint border,
2501 GLenum format,
2502 GLenum type,
2503 const GLvoid *pixels)
2504{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002505 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002506
2507 Extents size(width, height, 1);
2508 Texture *texture =
2509 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2510 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2511 format, type, reinterpret_cast<const uint8_t *>(pixels));
2512 if (error.isError())
2513 {
2514 recordError(error);
2515 }
2516}
2517
2518void Context::texImage3D(GLenum target,
2519 GLint level,
2520 GLint internalformat,
2521 GLsizei width,
2522 GLsizei height,
2523 GLsizei depth,
2524 GLint border,
2525 GLenum format,
2526 GLenum type,
2527 const GLvoid *pixels)
2528{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002529 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002530
2531 Extents size(width, height, depth);
2532 Texture *texture = getTargetTexture(target);
2533 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2534 format, type, reinterpret_cast<const uint8_t *>(pixels));
2535 if (error.isError())
2536 {
2537 recordError(error);
2538 }
2539}
2540
2541void Context::texSubImage2D(GLenum target,
2542 GLint level,
2543 GLint xoffset,
2544 GLint yoffset,
2545 GLsizei width,
2546 GLsizei height,
2547 GLenum format,
2548 GLenum type,
2549 const GLvoid *pixels)
2550{
2551 // Zero sized uploads are valid but no-ops
2552 if (width == 0 || height == 0)
2553 {
2554 return;
2555 }
2556
Jamie Madillad9f24e2016-02-12 09:27:24 -05002557 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002558
2559 Box area(xoffset, yoffset, 0, width, height, 1);
2560 Texture *texture =
2561 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2562 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2563 reinterpret_cast<const uint8_t *>(pixels));
2564 if (error.isError())
2565 {
2566 recordError(error);
2567 }
2568}
2569
2570void Context::texSubImage3D(GLenum target,
2571 GLint level,
2572 GLint xoffset,
2573 GLint yoffset,
2574 GLint zoffset,
2575 GLsizei width,
2576 GLsizei height,
2577 GLsizei depth,
2578 GLenum format,
2579 GLenum type,
2580 const GLvoid *pixels)
2581{
2582 // Zero sized uploads are valid but no-ops
2583 if (width == 0 || height == 0 || depth == 0)
2584 {
2585 return;
2586 }
2587
Jamie Madillad9f24e2016-02-12 09:27:24 -05002588 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002589
2590 Box area(xoffset, yoffset, zoffset, width, height, depth);
2591 Texture *texture = getTargetTexture(target);
2592 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2593 reinterpret_cast<const uint8_t *>(pixels));
2594 if (error.isError())
2595 {
2596 recordError(error);
2597 }
2598}
2599
2600void Context::compressedTexImage2D(GLenum target,
2601 GLint level,
2602 GLenum internalformat,
2603 GLsizei width,
2604 GLsizei height,
2605 GLint border,
2606 GLsizei imageSize,
2607 const GLvoid *data)
2608{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002609 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002610
2611 Extents size(width, height, 1);
2612 Texture *texture =
2613 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2614 Error error =
2615 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2616 imageSize, reinterpret_cast<const uint8_t *>(data));
2617 if (error.isError())
2618 {
2619 recordError(error);
2620 }
2621}
2622
2623void Context::compressedTexImage3D(GLenum target,
2624 GLint level,
2625 GLenum internalformat,
2626 GLsizei width,
2627 GLsizei height,
2628 GLsizei depth,
2629 GLint border,
2630 GLsizei imageSize,
2631 const GLvoid *data)
2632{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002633 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002634
2635 Extents size(width, height, depth);
2636 Texture *texture = getTargetTexture(target);
2637 Error error =
2638 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2639 imageSize, reinterpret_cast<const uint8_t *>(data));
2640 if (error.isError())
2641 {
2642 recordError(error);
2643 }
2644}
2645
2646void Context::compressedTexSubImage2D(GLenum target,
2647 GLint level,
2648 GLint xoffset,
2649 GLint yoffset,
2650 GLsizei width,
2651 GLsizei height,
2652 GLenum format,
2653 GLsizei imageSize,
2654 const GLvoid *data)
2655{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002656 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002657
2658 Box area(xoffset, yoffset, 0, width, height, 1);
2659 Texture *texture =
2660 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2661 Error error =
2662 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2663 imageSize, reinterpret_cast<const uint8_t *>(data));
2664 if (error.isError())
2665 {
2666 recordError(error);
2667 }
2668}
2669
2670void Context::compressedTexSubImage3D(GLenum target,
2671 GLint level,
2672 GLint xoffset,
2673 GLint yoffset,
2674 GLint zoffset,
2675 GLsizei width,
2676 GLsizei height,
2677 GLsizei depth,
2678 GLenum format,
2679 GLsizei imageSize,
2680 const GLvoid *data)
2681{
2682 // Zero sized uploads are valid but no-ops
2683 if (width == 0 || height == 0)
2684 {
2685 return;
2686 }
2687
Jamie Madillad9f24e2016-02-12 09:27:24 -05002688 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002689
2690 Box area(xoffset, yoffset, zoffset, width, height, depth);
2691 Texture *texture = getTargetTexture(target);
2692 Error error =
2693 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2694 imageSize, reinterpret_cast<const uint8_t *>(data));
2695 if (error.isError())
2696 {
2697 recordError(error);
2698 }
2699}
2700
Olli Etuaho4f667482016-03-30 15:56:35 +03002701void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2702{
2703 Buffer *buffer = getState().getTargetBuffer(target);
2704 ASSERT(buffer);
2705
2706 if (!buffer->isMapped())
2707 {
2708 *params = nullptr;
2709 }
2710 else
2711 {
2712 *params = buffer->getMapPointer();
2713 }
2714}
2715
2716GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2717{
2718 Buffer *buffer = getState().getTargetBuffer(target);
2719 ASSERT(buffer);
2720
2721 Error error = buffer->map(access);
2722 if (error.isError())
2723 {
2724 recordError(error);
2725 return nullptr;
2726 }
2727
2728 return buffer->getMapPointer();
2729}
2730
2731GLboolean Context::unmapBuffer(GLenum target)
2732{
2733 Buffer *buffer = getState().getTargetBuffer(target);
2734 ASSERT(buffer);
2735
2736 GLboolean result;
2737 Error error = buffer->unmap(&result);
2738 if (error.isError())
2739 {
2740 recordError(error);
2741 return GL_FALSE;
2742 }
2743
2744 return result;
2745}
2746
2747GLvoid *Context::mapBufferRange(GLenum target,
2748 GLintptr offset,
2749 GLsizeiptr length,
2750 GLbitfield access)
2751{
2752 Buffer *buffer = getState().getTargetBuffer(target);
2753 ASSERT(buffer);
2754
2755 Error error = buffer->mapRange(offset, length, access);
2756 if (error.isError())
2757 {
2758 recordError(error);
2759 return nullptr;
2760 }
2761
2762 return buffer->getMapPointer();
2763}
2764
2765void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2766{
2767 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2768}
2769
Jamie Madillad9f24e2016-02-12 09:27:24 -05002770void Context::syncStateForReadPixels()
2771{
2772 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2773}
2774
2775void Context::syncStateForTexImage()
2776{
2777 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2778}
2779
2780void Context::syncStateForClear()
2781{
2782 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2783}
2784
2785void Context::syncStateForBlit()
2786{
2787 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2788}
2789
Jamie Madillc29968b2016-01-20 11:17:23 -05002790} // namespace gl