blob: 61bb1720ee5e46e21963669fea761f5d95f75e99 [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{
Corentin Walleza2257da2016-04-19 16:43:12 -04001865 // Transform feedback detachment is handled by Context, because 0 is a valid
1866 // transform feedback, and a pointer to it must be passed from Context to State at
1867 // binding time.
1868
1869 // The OpenGL specification doesn't mention what should happen when the currently bound
1870 // transform feedback object is deleted. Since it is a container object, we treat it like
1871 // VAOs and FBOs and set the current bound transform feedback back to 0.
1872 if (mState.removeTransformFeedbackBinding(transformFeedback))
1873 {
1874 bindTransformFeedback(0);
1875 }
Geoff Langc8058452014-02-03 12:04:11 -05001876}
1877
Jamie Madilldc356042013-07-19 16:36:57 -04001878void Context::detachSampler(GLuint sampler)
1879{
Shannon Woods53a94a82014-06-24 15:20:36 -04001880 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001881}
1882
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001883void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1884{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001885 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001886}
1887
Jamie Madille29d1672013-07-19 16:36:57 -04001888void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1889{
1890 mResourceManager->checkSamplerAllocation(sampler);
1891
1892 Sampler *samplerObject = getSampler(sampler);
1893 ASSERT(samplerObject);
1894
Geoff Lang69cce582015-09-17 13:20:36 -04001895 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001896 switch (pname)
1897 {
Geoff Lang69cce582015-09-17 13:20:36 -04001898 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1899 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1900 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1901 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1902 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1903 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1904 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1905 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1906 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1907 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1908 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001909 }
Geoff Lang69cce582015-09-17 13:20:36 -04001910 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001911}
1912
1913void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1914{
1915 mResourceManager->checkSamplerAllocation(sampler);
1916
1917 Sampler *samplerObject = getSampler(sampler);
1918 ASSERT(samplerObject);
1919
Geoff Lang69cce582015-09-17 13:20:36 -04001920 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001921 switch (pname)
1922 {
Geoff Lang69cce582015-09-17 13:20:36 -04001923 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1924 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1925 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1926 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1927 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1928 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1929 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1930 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1931 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1932 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1933 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001934 }
Geoff Lang69cce582015-09-17 13:20:36 -04001935 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001936}
1937
Jamie Madill9675b802013-07-19 16:36:59 -04001938GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1939{
1940 mResourceManager->checkSamplerAllocation(sampler);
1941
1942 Sampler *samplerObject = getSampler(sampler);
1943 ASSERT(samplerObject);
1944
Geoff Lang69cce582015-09-17 13:20:36 -04001945 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001946 switch (pname)
1947 {
Geoff Lang69cce582015-09-17 13:20:36 -04001948 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1949 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1950 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1951 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1952 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1953 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001954 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1955 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001956 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1957 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1958 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001959 }
Geoff Lang69cce582015-09-17 13:20:36 -04001960 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001961}
1962
1963GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1964{
1965 mResourceManager->checkSamplerAllocation(sampler);
1966
1967 Sampler *samplerObject = getSampler(sampler);
1968 ASSERT(samplerObject);
1969
Geoff Lang69cce582015-09-17 13:20:36 -04001970 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001971 switch (pname)
1972 {
Geoff Lang69cce582015-09-17 13:20:36 -04001973 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1974 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1975 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1976 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1977 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1978 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1979 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1980 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1981 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1982 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1983 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001984 }
Geoff Lang69cce582015-09-17 13:20:36 -04001985 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001986}
1987
Olli Etuahof0fee072016-03-30 15:11:58 +03001988void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1989{
1990 gl::Program *programObject = getProgram(program);
1991 ASSERT(programObject != nullptr);
1992
1993 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1994 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1995}
1996
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001997void Context::initRendererString()
1998{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001999 std::ostringstream rendererString;
2000 rendererString << "ANGLE (";
2001 rendererString << mRenderer->getRendererDescription();
2002 rendererString << ")";
2003
Geoff Langcec35902014-04-16 10:52:36 -04002004 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002005}
2006
Geoff Langc0b9ef42014-07-02 10:02:37 -04002007const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002008{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002009 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002010}
2011
Geoff Langcec35902014-04-16 10:52:36 -04002012void Context::initExtensionStrings()
2013{
Geoff Lang493daf52014-07-03 13:38:44 -04002014 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002015
Geoff Langc0b9ef42014-07-02 10:02:37 -04002016 std::ostringstream combinedStringStream;
2017 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2018 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002019}
2020
Geoff Langc0b9ef42014-07-02 10:02:37 -04002021const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002022{
2023 return mExtensionString;
2024}
2025
Geoff Langc0b9ef42014-07-02 10:02:37 -04002026const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002027{
2028 return mExtensionStrings[idx];
2029}
2030
2031size_t Context::getExtensionStringCount() const
2032{
2033 return mExtensionStrings.size();
2034}
2035
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002036void Context::beginTransformFeedback(GLenum primitiveMode)
2037{
2038 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2039 ASSERT(transformFeedback != nullptr);
2040 ASSERT(!transformFeedback->isPaused());
2041
2042 transformFeedback->begin(primitiveMode, getState().getProgram());
2043}
2044
2045bool Context::hasActiveTransformFeedback(GLuint program) const
2046{
2047 for (auto pair : mTransformFeedbackMap)
2048 {
2049 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2050 {
2051 return true;
2052 }
2053 }
2054 return false;
2055}
2056
Geoff Lang493daf52014-07-03 13:38:44 -04002057void Context::initCaps(GLuint clientVersion)
2058{
2059 mCaps = mRenderer->getRendererCaps();
2060
2061 mExtensions = mRenderer->getRendererExtensions();
2062
Austin Kinross02df7962015-07-01 10:03:42 -07002063 mLimitations = mRenderer->getRendererLimitations();
2064
Geoff Lang493daf52014-07-03 13:38:44 -04002065 if (clientVersion < 3)
2066 {
2067 // Disable ES3+ extensions
2068 mExtensions.colorBufferFloat = false;
2069 }
2070
2071 if (clientVersion > 2)
2072 {
2073 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2074 //mExtensions.sRGB = false;
2075 }
2076
Geoff Lang70d0f492015-12-10 17:45:46 -05002077 // Explicitly enable GL_KHR_debug
2078 mExtensions.debug = true;
2079 mExtensions.maxDebugMessageLength = 1024;
2080 mExtensions.maxDebugLoggedMessages = 1024;
2081 mExtensions.maxDebugGroupStackDepth = 1024;
2082 mExtensions.maxLabelLength = 1024;
2083
Geoff Lang301d1612014-07-09 10:34:37 -04002084 // Apply implementation limits
2085 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002086 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2087 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2088
2089 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002090
Geoff Lang900013c2014-07-07 11:32:19 -04002091 mCaps.compressedTextureFormats.clear();
2092
Geoff Lang493daf52014-07-03 13:38:44 -04002093 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2094 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2095 {
2096 GLenum format = i->first;
2097 TextureCaps formatCaps = i->second;
2098
Geoff Lang5d601382014-07-22 15:14:06 -04002099 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002100
Geoff Lang0d8b7242015-09-09 14:56:53 -04002101 // Update the format caps based on the client version and extensions.
2102 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2103 // ES3.
2104 formatCaps.texturable =
2105 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2106 formatCaps.renderable =
2107 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2108 formatCaps.filterable =
2109 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002110
2111 // OpenGL ES does not support multisampling with integer formats
2112 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002113 {
Geoff Langd87878e2014-09-19 15:42:59 -04002114 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002115 }
Geoff Langd87878e2014-09-19 15:42:59 -04002116
2117 if (formatCaps.texturable && formatInfo.compressed)
2118 {
2119 mCaps.compressedTextureFormats.push_back(format);
2120 }
2121
2122 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002123 }
2124}
2125
Jamie Madill1b94d432015-08-07 13:23:23 -04002126void Context::syncRendererState()
2127{
2128 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002129 mRenderer->syncState(mState, dirtyBits);
2130 mState.clearDirtyBits();
2131 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002132}
2133
Jamie Madillad9f24e2016-02-12 09:27:24 -05002134void Context::syncRendererState(const State::DirtyBits &bitMask,
2135 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002136{
2137 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002138 mRenderer->syncState(mState, dirtyBits);
2139 mState.clearDirtyBits(dirtyBits);
2140
Jamie Madillad9f24e2016-02-12 09:27:24 -05002141 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002142}
Jamie Madillc29968b2016-01-20 11:17:23 -05002143
2144void Context::blitFramebuffer(GLint srcX0,
2145 GLint srcY0,
2146 GLint srcX1,
2147 GLint srcY1,
2148 GLint dstX0,
2149 GLint dstY0,
2150 GLint dstX1,
2151 GLint dstY1,
2152 GLbitfield mask,
2153 GLenum filter)
2154{
2155 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2156 ASSERT(readFramebuffer);
2157
2158 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2159 ASSERT(drawFramebuffer);
2160
2161 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2162 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2163
Jamie Madillad9f24e2016-02-12 09:27:24 -05002164 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002165
2166 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2167 if (error.isError())
2168 {
2169 recordError(error);
2170 return;
2171 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002172}
Jamie Madillc29968b2016-01-20 11:17:23 -05002173
2174void Context::clear(GLbitfield mask)
2175{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002176 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002177
2178 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2179 if (error.isError())
2180 {
2181 recordError(error);
2182 }
2183}
2184
2185void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2186{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002187 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002188
2189 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2190 if (error.isError())
2191 {
2192 recordError(error);
2193 }
2194}
2195
2196void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2197{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002198 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002199
2200 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2201 if (error.isError())
2202 {
2203 recordError(error);
2204 }
2205}
2206
2207void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2208{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002209 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002210
2211 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2212 if (error.isError())
2213 {
2214 recordError(error);
2215 }
2216}
2217
2218void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2219{
2220 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2221 ASSERT(framebufferObject);
2222
2223 // If a buffer is not present, the clear has no effect
2224 if (framebufferObject->getDepthbuffer() == nullptr &&
2225 framebufferObject->getStencilbuffer() == nullptr)
2226 {
2227 return;
2228 }
2229
Jamie Madillad9f24e2016-02-12 09:27:24 -05002230 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002231
2232 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2233 if (error.isError())
2234 {
2235 recordError(error);
2236 }
2237}
2238
2239void Context::readPixels(GLint x,
2240 GLint y,
2241 GLsizei width,
2242 GLsizei height,
2243 GLenum format,
2244 GLenum type,
2245 GLvoid *pixels)
2246{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002247 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002248
2249 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2250 ASSERT(framebufferObject);
2251
2252 Rectangle area(x, y, width, height);
2253 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2254 if (error.isError())
2255 {
2256 recordError(error);
2257 }
2258}
2259
2260void Context::copyTexImage2D(GLenum target,
2261 GLint level,
2262 GLenum internalformat,
2263 GLint x,
2264 GLint y,
2265 GLsizei width,
2266 GLsizei height,
2267 GLint border)
2268{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002269 // Only sync the read FBO
2270 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2271
Jamie Madillc29968b2016-01-20 11:17:23 -05002272 Rectangle sourceArea(x, y, width, height);
2273
2274 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2275 Texture *texture =
2276 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2277 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2278 if (error.isError())
2279 {
2280 recordError(error);
2281 }
2282}
2283
2284void Context::copyTexSubImage2D(GLenum target,
2285 GLint level,
2286 GLint xoffset,
2287 GLint yoffset,
2288 GLint x,
2289 GLint y,
2290 GLsizei width,
2291 GLsizei height)
2292{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002293 // Only sync the read FBO
2294 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2295
Jamie Madillc29968b2016-01-20 11:17:23 -05002296 Offset destOffset(xoffset, yoffset, 0);
2297 Rectangle sourceArea(x, y, width, height);
2298
2299 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2300 Texture *texture =
2301 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2302 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2303 if (error.isError())
2304 {
2305 recordError(error);
2306 }
2307}
2308
2309void Context::copyTexSubImage3D(GLenum target,
2310 GLint level,
2311 GLint xoffset,
2312 GLint yoffset,
2313 GLint zoffset,
2314 GLint x,
2315 GLint y,
2316 GLsizei width,
2317 GLsizei height)
2318{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002319 // Only sync the read FBO
2320 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2321
Jamie Madillc29968b2016-01-20 11:17:23 -05002322 Offset destOffset(xoffset, yoffset, zoffset);
2323 Rectangle sourceArea(x, y, width, height);
2324
2325 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2326 Texture *texture = getTargetTexture(target);
2327 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2328 if (error.isError())
2329 {
2330 recordError(error);
2331 }
2332}
2333
2334void Context::framebufferTexture2D(GLenum target,
2335 GLenum attachment,
2336 GLenum textarget,
2337 GLuint texture,
2338 GLint level)
2339{
2340 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2341 ASSERT(framebuffer);
2342
2343 if (texture != 0)
2344 {
2345 Texture *textureObj = getTexture(texture);
2346
2347 ImageIndex index = ImageIndex::MakeInvalid();
2348
2349 if (textarget == GL_TEXTURE_2D)
2350 {
2351 index = ImageIndex::Make2D(level);
2352 }
2353 else
2354 {
2355 ASSERT(IsCubeMapTextureTarget(textarget));
2356 index = ImageIndex::MakeCube(textarget, level);
2357 }
2358
2359 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2360 }
2361 else
2362 {
2363 framebuffer->resetAttachment(attachment);
2364 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002365
2366 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002367}
2368
2369void Context::framebufferRenderbuffer(GLenum target,
2370 GLenum attachment,
2371 GLenum renderbuffertarget,
2372 GLuint renderbuffer)
2373{
2374 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2375 ASSERT(framebuffer);
2376
2377 if (renderbuffer != 0)
2378 {
2379 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2380 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2381 renderbufferObject);
2382 }
2383 else
2384 {
2385 framebuffer->resetAttachment(attachment);
2386 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002387
2388 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002389}
2390
2391void Context::framebufferTextureLayer(GLenum target,
2392 GLenum attachment,
2393 GLuint texture,
2394 GLint level,
2395 GLint layer)
2396{
2397 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2398 ASSERT(framebuffer);
2399
2400 if (texture != 0)
2401 {
2402 Texture *textureObject = getTexture(texture);
2403
2404 ImageIndex index = ImageIndex::MakeInvalid();
2405
2406 if (textureObject->getTarget() == GL_TEXTURE_3D)
2407 {
2408 index = ImageIndex::Make3D(level, layer);
2409 }
2410 else
2411 {
2412 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2413 index = ImageIndex::Make2DArray(level, layer);
2414 }
2415
2416 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2417 }
2418 else
2419 {
2420 framebuffer->resetAttachment(attachment);
2421 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002422
2423 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002424}
2425
2426void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2427{
2428 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2429 ASSERT(framebuffer);
2430 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002431 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002432}
2433
2434void Context::readBuffer(GLenum mode)
2435{
2436 Framebuffer *readFBO = mState.getReadFramebuffer();
2437 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002438 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002439}
2440
2441void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2442{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002443 // Only sync the FBO
2444 mState.syncDirtyObject(target);
2445
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2447 ASSERT(framebuffer);
2448
2449 // The specification isn't clear what should be done when the framebuffer isn't complete.
2450 // We leave it up to the framebuffer implementation to decide what to do.
2451 Error error = framebuffer->discard(numAttachments, attachments);
2452 if (error.isError())
2453 {
2454 recordError(error);
2455 }
2456}
2457
2458void Context::invalidateFramebuffer(GLenum target,
2459 GLsizei numAttachments,
2460 const GLenum *attachments)
2461{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002462 // Only sync the FBO
2463 mState.syncDirtyObject(target);
2464
Jamie Madillc29968b2016-01-20 11:17:23 -05002465 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2466 ASSERT(framebuffer);
2467
2468 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2469 {
2470 Error error = framebuffer->invalidate(numAttachments, attachments);
2471 if (error.isError())
2472 {
2473 recordError(error);
2474 return;
2475 }
2476 }
2477}
2478
2479void Context::invalidateSubFramebuffer(GLenum target,
2480 GLsizei numAttachments,
2481 const GLenum *attachments,
2482 GLint x,
2483 GLint y,
2484 GLsizei width,
2485 GLsizei height)
2486{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002487 // Only sync the FBO
2488 mState.syncDirtyObject(target);
2489
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2491 ASSERT(framebuffer);
2492
2493 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2494 {
2495 Rectangle area(x, y, width, height);
2496 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2497 if (error.isError())
2498 {
2499 recordError(error);
2500 return;
2501 }
2502 }
2503}
2504
Jamie Madill73a84962016-02-12 09:27:23 -05002505void Context::texImage2D(GLenum target,
2506 GLint level,
2507 GLint internalformat,
2508 GLsizei width,
2509 GLsizei height,
2510 GLint border,
2511 GLenum format,
2512 GLenum type,
2513 const GLvoid *pixels)
2514{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002516
2517 Extents size(width, height, 1);
2518 Texture *texture =
2519 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2520 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2521 format, type, reinterpret_cast<const uint8_t *>(pixels));
2522 if (error.isError())
2523 {
2524 recordError(error);
2525 }
2526}
2527
2528void Context::texImage3D(GLenum target,
2529 GLint level,
2530 GLint internalformat,
2531 GLsizei width,
2532 GLsizei height,
2533 GLsizei depth,
2534 GLint border,
2535 GLenum format,
2536 GLenum type,
2537 const GLvoid *pixels)
2538{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002539 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002540
2541 Extents size(width, height, depth);
2542 Texture *texture = getTargetTexture(target);
2543 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2544 format, type, reinterpret_cast<const uint8_t *>(pixels));
2545 if (error.isError())
2546 {
2547 recordError(error);
2548 }
2549}
2550
2551void Context::texSubImage2D(GLenum target,
2552 GLint level,
2553 GLint xoffset,
2554 GLint yoffset,
2555 GLsizei width,
2556 GLsizei height,
2557 GLenum format,
2558 GLenum type,
2559 const GLvoid *pixels)
2560{
2561 // Zero sized uploads are valid but no-ops
2562 if (width == 0 || height == 0)
2563 {
2564 return;
2565 }
2566
Jamie Madillad9f24e2016-02-12 09:27:24 -05002567 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002568
2569 Box area(xoffset, yoffset, 0, width, height, 1);
2570 Texture *texture =
2571 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2572 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2573 reinterpret_cast<const uint8_t *>(pixels));
2574 if (error.isError())
2575 {
2576 recordError(error);
2577 }
2578}
2579
2580void Context::texSubImage3D(GLenum target,
2581 GLint level,
2582 GLint xoffset,
2583 GLint yoffset,
2584 GLint zoffset,
2585 GLsizei width,
2586 GLsizei height,
2587 GLsizei depth,
2588 GLenum format,
2589 GLenum type,
2590 const GLvoid *pixels)
2591{
2592 // Zero sized uploads are valid but no-ops
2593 if (width == 0 || height == 0 || depth == 0)
2594 {
2595 return;
2596 }
2597
Jamie Madillad9f24e2016-02-12 09:27:24 -05002598 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002599
2600 Box area(xoffset, yoffset, zoffset, width, height, depth);
2601 Texture *texture = getTargetTexture(target);
2602 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2603 reinterpret_cast<const uint8_t *>(pixels));
2604 if (error.isError())
2605 {
2606 recordError(error);
2607 }
2608}
2609
2610void Context::compressedTexImage2D(GLenum target,
2611 GLint level,
2612 GLenum internalformat,
2613 GLsizei width,
2614 GLsizei height,
2615 GLint border,
2616 GLsizei imageSize,
2617 const GLvoid *data)
2618{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002619 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002620
2621 Extents size(width, height, 1);
2622 Texture *texture =
2623 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2624 Error error =
2625 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2626 imageSize, reinterpret_cast<const uint8_t *>(data));
2627 if (error.isError())
2628 {
2629 recordError(error);
2630 }
2631}
2632
2633void Context::compressedTexImage3D(GLenum target,
2634 GLint level,
2635 GLenum internalformat,
2636 GLsizei width,
2637 GLsizei height,
2638 GLsizei depth,
2639 GLint border,
2640 GLsizei imageSize,
2641 const GLvoid *data)
2642{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002643 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002644
2645 Extents size(width, height, depth);
2646 Texture *texture = getTargetTexture(target);
2647 Error error =
2648 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2649 imageSize, reinterpret_cast<const uint8_t *>(data));
2650 if (error.isError())
2651 {
2652 recordError(error);
2653 }
2654}
2655
2656void Context::compressedTexSubImage2D(GLenum target,
2657 GLint level,
2658 GLint xoffset,
2659 GLint yoffset,
2660 GLsizei width,
2661 GLsizei height,
2662 GLenum format,
2663 GLsizei imageSize,
2664 const GLvoid *data)
2665{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002666 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002667
2668 Box area(xoffset, yoffset, 0, width, height, 1);
2669 Texture *texture =
2670 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2671 Error error =
2672 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2673 imageSize, reinterpret_cast<const uint8_t *>(data));
2674 if (error.isError())
2675 {
2676 recordError(error);
2677 }
2678}
2679
2680void Context::compressedTexSubImage3D(GLenum target,
2681 GLint level,
2682 GLint xoffset,
2683 GLint yoffset,
2684 GLint zoffset,
2685 GLsizei width,
2686 GLsizei height,
2687 GLsizei depth,
2688 GLenum format,
2689 GLsizei imageSize,
2690 const GLvoid *data)
2691{
2692 // Zero sized uploads are valid but no-ops
2693 if (width == 0 || height == 0)
2694 {
2695 return;
2696 }
2697
Jamie Madillad9f24e2016-02-12 09:27:24 -05002698 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002699
2700 Box area(xoffset, yoffset, zoffset, width, height, depth);
2701 Texture *texture = getTargetTexture(target);
2702 Error error =
2703 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2704 imageSize, reinterpret_cast<const uint8_t *>(data));
2705 if (error.isError())
2706 {
2707 recordError(error);
2708 }
2709}
2710
Olli Etuaho4f667482016-03-30 15:56:35 +03002711void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2712{
2713 Buffer *buffer = getState().getTargetBuffer(target);
2714 ASSERT(buffer);
2715
2716 if (!buffer->isMapped())
2717 {
2718 *params = nullptr;
2719 }
2720 else
2721 {
2722 *params = buffer->getMapPointer();
2723 }
2724}
2725
2726GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2727{
2728 Buffer *buffer = getState().getTargetBuffer(target);
2729 ASSERT(buffer);
2730
2731 Error error = buffer->map(access);
2732 if (error.isError())
2733 {
2734 recordError(error);
2735 return nullptr;
2736 }
2737
2738 return buffer->getMapPointer();
2739}
2740
2741GLboolean Context::unmapBuffer(GLenum target)
2742{
2743 Buffer *buffer = getState().getTargetBuffer(target);
2744 ASSERT(buffer);
2745
2746 GLboolean result;
2747 Error error = buffer->unmap(&result);
2748 if (error.isError())
2749 {
2750 recordError(error);
2751 return GL_FALSE;
2752 }
2753
2754 return result;
2755}
2756
2757GLvoid *Context::mapBufferRange(GLenum target,
2758 GLintptr offset,
2759 GLsizeiptr length,
2760 GLbitfield access)
2761{
2762 Buffer *buffer = getState().getTargetBuffer(target);
2763 ASSERT(buffer);
2764
2765 Error error = buffer->mapRange(offset, length, access);
2766 if (error.isError())
2767 {
2768 recordError(error);
2769 return nullptr;
2770 }
2771
2772 return buffer->getMapPointer();
2773}
2774
2775void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2776{
2777 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2778}
2779
Jamie Madillad9f24e2016-02-12 09:27:24 -05002780void Context::syncStateForReadPixels()
2781{
2782 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2783}
2784
2785void Context::syncStateForTexImage()
2786{
2787 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2788}
2789
2790void Context::syncStateForClear()
2791{
2792 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2793}
2794
2795void Context::syncStateForBlit()
2796{
2797 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2798}
2799
Jamie Madillc29968b2016-01-20 11:17:23 -05002800} // namespace gl