blob: 0af3cacb2fcc078cd827bf78b95b694eda303f60 [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
Jamie Madille6382c32014-11-07 15:05:26 -0500191 mState.initializeZeroTextures(mZeroTextures);
192
Jamie Madill57a89722013-07-02 11:57:03 -0400193 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000194 bindArrayBuffer(0);
195 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400196
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000197 bindRenderbuffer(0);
198
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000199 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400200 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000201 {
202 bindIndexedUniformBuffer(0, i, 0, -1);
203 }
204
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000205 bindCopyReadBuffer(0);
206 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000207 bindPixelPackBuffer(0);
208 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000209
Geoff Lang1a683462015-09-29 15:09:59 -0400210 if (mClientVersion >= 3)
211 {
212 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
213 // In the initial state, a default transform feedback object is bound and treated as
214 // a transform feedback object with a name of zero. That object is bound any time
215 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400216 bindTransformFeedback(0);
217 }
Geoff Langc8058452014-02-03 12:04:11 -0500218
Jamie Madill83f349e2015-09-23 09:50:36 -0400219 mCompiler = new Compiler(mRenderer, getData());
Jamie Madillad9f24e2016-02-12 09:27:24 -0500220
221 // Initialize dirty bit masks
222 // TODO(jmadill): additional ES3 state
223 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
224 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
225 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
226 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
227 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
228 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
229 // No dirty objects.
230
231 // Readpixels uses the pack state and read FBO
232 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
233 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
234 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
235 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
236 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
237 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
238
239 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
240 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
241 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
242 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
243 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
244 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
245 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
246 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
247 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
248 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
249 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
250 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
251
252 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
253 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
254 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
255 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000256}
257
258Context::~Context()
259{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500260 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000261
Corentin Wallez37c39792015-08-20 14:19:46 -0400262 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000263 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400264 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400265 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400266 {
267 SafeDelete(framebuffer.second);
268 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000269 }
270
Corentin Wallez80b24112015-08-25 16:41:57 -0400271 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000272 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400273 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000274 }
275
Corentin Wallez80b24112015-08-25 16:41:57 -0400276 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400278 if (query.second != nullptr)
279 {
280 query.second->release();
281 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282 }
283
Corentin Wallez80b24112015-08-25 16:41:57 -0400284 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400285 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400286 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400287 }
288
Corentin Wallez80b24112015-08-25 16:41:57 -0400289 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500290 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500291 if (transformFeedback.second != nullptr)
292 {
293 transformFeedback.second->release();
294 }
Geoff Langc8058452014-02-03 12:04:11 -0500295 }
296
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400298 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400300 }
301 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000302
Corentin Wallez51706ea2015-08-07 14:39:22 -0400303 if (mCurrentSurface != nullptr)
304 {
305 releaseSurface();
306 }
307
Jamie Madill1e9ae072014-11-06 15:27:21 -0500308 if (mResourceManager)
309 {
310 mResourceManager->release();
311 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500312
313 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314}
315
daniel@transgaming.comad629872012-11-28 19:32:06 +0000316void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000317{
Jamie Madill77a72f62015-04-14 11:18:32 -0400318 ASSERT(surface != nullptr);
319
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000320 if (!mHasBeenCurrent)
321 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000322 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400323 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000324
Shannon Woods53a94a82014-06-24 15:20:36 -0400325 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
326 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000327
328 mHasBeenCurrent = true;
329 }
330
Jamie Madill1b94d432015-08-07 13:23:23 -0400331 // TODO(jmadill): Rework this when we support ContextImpl
332 mState.setAllDirtyBits();
333
Corentin Wallez51706ea2015-08-07 14:39:22 -0400334 if (mCurrentSurface)
335 {
336 releaseSurface();
337 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000338 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400339 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000340
Corentin Wallez37c39792015-08-20 14:19:46 -0400341 // Update default framebuffer, the binding of the previous default
342 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400343 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400344 Framebuffer *newDefault = surface->getDefaultFramebuffer();
345 if (mState.getReadFramebuffer() == nullptr)
346 {
347 mState.setReadFramebufferBinding(newDefault);
348 }
349 if (mState.getDrawFramebuffer() == nullptr)
350 {
351 mState.setDrawFramebufferBinding(newDefault);
352 }
353 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400354 }
Ian Ewell292f0052016-02-04 10:37:32 -0500355
356 // Notify the renderer of a context switch
357 mRenderer->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000358}
359
Jamie Madill77a72f62015-04-14 11:18:32 -0400360void Context::releaseSurface()
361{
Corentin Wallez37c39792015-08-20 14:19:46 -0400362 ASSERT(mCurrentSurface != nullptr);
363
364 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400365 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400366 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
367 if (mState.getReadFramebuffer() == currentDefault)
368 {
369 mState.setReadFramebufferBinding(nullptr);
370 }
371 if (mState.getDrawFramebuffer() == currentDefault)
372 {
373 mState.setDrawFramebufferBinding(nullptr);
374 }
375 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400376 }
377
Corentin Wallez51706ea2015-08-07 14:39:22 -0400378 mCurrentSurface->setIsCurrent(false);
379 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400380}
381
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000382// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000383void Context::markContextLost()
384{
385 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
386 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
387 mContextLost = true;
388}
389
390bool Context::isContextLost()
391{
392 return mContextLost;
393}
394
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395GLuint Context::createBuffer()
396{
397 return mResourceManager->createBuffer();
398}
399
400GLuint Context::createProgram()
401{
402 return mResourceManager->createProgram();
403}
404
405GLuint Context::createShader(GLenum type)
406{
Jamie Madill006cbc52015-09-23 16:47:54 -0400407 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000408}
409
410GLuint Context::createTexture()
411{
412 return mResourceManager->createTexture();
413}
414
415GLuint Context::createRenderbuffer()
416{
417 return mResourceManager->createRenderbuffer();
418}
419
Geoff Lang882033e2014-09-30 11:26:07 -0400420GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400421{
422 GLuint handle = mResourceManager->createFenceSync();
423
Cooper Partind8e62a32015-01-29 15:21:25 -0800424 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400425}
426
Jamie Madill57a89722013-07-02 11:57:03 -0400427GLuint Context::createVertexArray()
428{
Geoff Lang36167ab2015-12-07 10:27:14 -0500429 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
430 mVertexArrayMap[vertexArray] = nullptr;
431 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400432}
433
Jamie Madilldc356042013-07-19 16:36:57 -0400434GLuint Context::createSampler()
435{
436 return mResourceManager->createSampler();
437}
438
Geoff Langc8058452014-02-03 12:04:11 -0500439GLuint Context::createTransformFeedback()
440{
Geoff Lang36167ab2015-12-07 10:27:14 -0500441 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
442 mTransformFeedbackMap[transformFeedback] = nullptr;
443 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500444}
445
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446// Returns an unused framebuffer name
447GLuint Context::createFramebuffer()
448{
449 GLuint handle = mFramebufferHandleAllocator.allocate();
450
451 mFramebufferMap[handle] = NULL;
452
453 return handle;
454}
455
Jamie Madill33dc8432013-07-26 11:55:05 -0400456GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000457{
Jamie Madill33dc8432013-07-26 11:55:05 -0400458 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000459
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700460 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000461
462 return handle;
463}
464
465// Returns an unused query name
466GLuint Context::createQuery()
467{
468 GLuint handle = mQueryHandleAllocator.allocate();
469
470 mQueryMap[handle] = NULL;
471
472 return handle;
473}
474
475void Context::deleteBuffer(GLuint buffer)
476{
477 if (mResourceManager->getBuffer(buffer))
478 {
479 detachBuffer(buffer);
480 }
Jamie Madill893ab082014-05-16 16:56:10 -0400481
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000482 mResourceManager->deleteBuffer(buffer);
483}
484
485void Context::deleteShader(GLuint shader)
486{
487 mResourceManager->deleteShader(shader);
488}
489
490void Context::deleteProgram(GLuint program)
491{
492 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493}
494
495void Context::deleteTexture(GLuint texture)
496{
497 if (mResourceManager->getTexture(texture))
498 {
499 detachTexture(texture);
500 }
501
502 mResourceManager->deleteTexture(texture);
503}
504
505void Context::deleteRenderbuffer(GLuint renderbuffer)
506{
507 if (mResourceManager->getRenderbuffer(renderbuffer))
508 {
509 detachRenderbuffer(renderbuffer);
510 }
Jamie Madill893ab082014-05-16 16:56:10 -0400511
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000512 mResourceManager->deleteRenderbuffer(renderbuffer);
513}
514
Jamie Madillcd055f82013-07-26 11:55:15 -0400515void Context::deleteFenceSync(GLsync fenceSync)
516{
517 // The spec specifies the underlying Fence object is not deleted until all current
518 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
519 // and since our API is currently designed for being called from a single thread, we can delete
520 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700521 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400522}
523
Jamie Madill57a89722013-07-02 11:57:03 -0400524void Context::deleteVertexArray(GLuint vertexArray)
525{
Geoff Lang36167ab2015-12-07 10:27:14 -0500526 auto iter = mVertexArrayMap.find(vertexArray);
527 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000528 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500529 VertexArray *vertexArrayObject = iter->second;
530 if (vertexArrayObject != nullptr)
531 {
532 detachVertexArray(vertexArray);
533 delete vertexArrayObject;
534 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000535
Geoff Lang36167ab2015-12-07 10:27:14 -0500536 mVertexArrayMap.erase(iter);
537 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400538 }
539}
540
Jamie Madilldc356042013-07-19 16:36:57 -0400541void Context::deleteSampler(GLuint sampler)
542{
543 if (mResourceManager->getSampler(sampler))
544 {
545 detachSampler(sampler);
546 }
547
548 mResourceManager->deleteSampler(sampler);
549}
550
Geoff Langc8058452014-02-03 12:04:11 -0500551void Context::deleteTransformFeedback(GLuint transformFeedback)
552{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500553 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500554 if (iter != mTransformFeedbackMap.end())
555 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500556 TransformFeedback *transformFeedbackObject = iter->second;
557 if (transformFeedbackObject != nullptr)
558 {
559 detachTransformFeedback(transformFeedback);
560 transformFeedbackObject->release();
561 }
562
Geoff Lang50b3fe82015-12-08 14:49:12 +0000563 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500564 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500565 }
566}
567
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000568void Context::deleteFramebuffer(GLuint framebuffer)
569{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500570 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000571
572 if (framebufferObject != mFramebufferMap.end())
573 {
574 detachFramebuffer(framebuffer);
575
576 mFramebufferHandleAllocator.release(framebufferObject->first);
577 delete framebufferObject->second;
578 mFramebufferMap.erase(framebufferObject);
579 }
580}
581
Jamie Madill33dc8432013-07-26 11:55:05 -0400582void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500584 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585
Jamie Madill33dc8432013-07-26 11:55:05 -0400586 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400588 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000589 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400590 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000591 }
592}
593
594void Context::deleteQuery(GLuint query)
595{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500596 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597 if (queryObject != mQueryMap.end())
598 {
599 mQueryHandleAllocator.release(queryObject->first);
600 if (queryObject->second)
601 {
602 queryObject->second->release();
603 }
604 mQueryMap.erase(queryObject);
605 }
606}
607
Geoff Lang70d0f492015-12-10 17:45:46 -0500608Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609{
610 return mResourceManager->getBuffer(handle);
611}
612
Geoff Lang48dcae72014-02-05 16:28:24 -0500613Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000614{
615 return mResourceManager->getShader(handle);
616}
617
Geoff Lang48dcae72014-02-05 16:28:24 -0500618Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000619{
620 return mResourceManager->getProgram(handle);
621}
622
Jamie Madill570f7c82014-07-03 10:38:54 -0400623Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000624{
625 return mResourceManager->getTexture(handle);
626}
627
Geoff Lang70d0f492015-12-10 17:45:46 -0500628Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629{
630 return mResourceManager->getRenderbuffer(handle);
631}
632
Jamie Madillcd055f82013-07-26 11:55:15 -0400633FenceSync *Context::getFenceSync(GLsync handle) const
634{
Minmin Gong794e0002015-04-07 18:31:54 -0700635 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400636}
637
Jamie Madill57a89722013-07-02 11:57:03 -0400638VertexArray *Context::getVertexArray(GLuint handle) const
639{
640 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500641 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400642}
643
Jamie Madilldc356042013-07-19 16:36:57 -0400644Sampler *Context::getSampler(GLuint handle) const
645{
646 return mResourceManager->getSampler(handle);
647}
648
Geoff Langc8058452014-02-03 12:04:11 -0500649TransformFeedback *Context::getTransformFeedback(GLuint handle) const
650{
Geoff Lang36167ab2015-12-07 10:27:14 -0500651 auto iter = mTransformFeedbackMap.find(handle);
652 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500653}
654
Geoff Lang70d0f492015-12-10 17:45:46 -0500655LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
656{
657 switch (identifier)
658 {
659 case GL_BUFFER:
660 return getBuffer(name);
661 case GL_SHADER:
662 return getShader(name);
663 case GL_PROGRAM:
664 return getProgram(name);
665 case GL_VERTEX_ARRAY:
666 return getVertexArray(name);
667 case GL_QUERY:
668 return getQuery(name);
669 case GL_TRANSFORM_FEEDBACK:
670 return getTransformFeedback(name);
671 case GL_SAMPLER:
672 return getSampler(name);
673 case GL_TEXTURE:
674 return getTexture(name);
675 case GL_RENDERBUFFER:
676 return getRenderbuffer(name);
677 case GL_FRAMEBUFFER:
678 return getFramebuffer(name);
679 default:
680 UNREACHABLE();
681 return nullptr;
682 }
683}
684
685LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
686{
687 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
688}
689
Jamie Madilldc356042013-07-19 16:36:57 -0400690bool Context::isSampler(GLuint samplerName) const
691{
692 return mResourceManager->isSampler(samplerName);
693}
694
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500695void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000696{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500697 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
698 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000699}
700
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500701void Context::bindElementArrayBuffer(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.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000705}
706
Jamie Madilldedd7b92014-11-05 16:30:36 -0500707void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000710
Jamie Madilldedd7b92014-11-05 16:30:36 -0500711 if (handle == 0)
712 {
713 texture = mZeroTextures[target].get();
714 }
715 else
716 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500717 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500718 }
719
720 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500721 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000722}
723
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500724void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000725{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500726 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
727 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000728}
729
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500730void Context::bindDrawFramebuffer(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.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000734}
735
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500736void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000737{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500738 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
739 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740}
741
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500742void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400743{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500744 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
745 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400746}
747
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500748void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400749{
Geoff Lang76b10c92014-09-05 16:28:14 -0400750 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500751 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
752 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400753}
754
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500755void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000756{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500757 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
758 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000759}
760
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500761void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
762 GLuint index,
763 GLintptr offset,
764 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000765{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500766 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
767 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000768}
769
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500770void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000771{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500772 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
773 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000774}
775
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500776void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
777 GLuint index,
778 GLintptr offset,
779 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000780{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500781 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
782 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000783}
784
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500785void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000786{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500787 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
788 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000789}
790
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500791void Context::bindCopyWriteBuffer(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.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000795}
796
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000798{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
800 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000801}
802
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803void Context::bindPixelUnpackBuffer(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.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000807}
808
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000809void Context::useProgram(GLuint program)
810{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500811 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000812}
813
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500814void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500815{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500816 TransformFeedback *transformFeedback =
817 checkTransformFeedbackAllocation(transformFeedbackHandle);
818 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500819}
820
Geoff Lang5aad9672014-09-08 11:10:42 -0400821Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400824 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825
Geoff Lang5aad9672014-09-08 11:10:42 -0400826 // begin query
827 Error error = queryObject->begin();
828 if (error.isError())
829 {
830 return error;
831 }
832
833 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400834 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835
Geoff Lang5aad9672014-09-08 11:10:42 -0400836 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837}
838
Geoff Lang5aad9672014-09-08 11:10:42 -0400839Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000840{
Shannon Woods53a94a82014-06-24 15:20:36 -0400841 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400842 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843
Geoff Lang5aad9672014-09-08 11:10:42 -0400844 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845
Geoff Lang5aad9672014-09-08 11:10:42 -0400846 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400847 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400848
849 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850}
851
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500852Error Context::queryCounter(GLuint id, GLenum target)
853{
854 ASSERT(target == GL_TIMESTAMP_EXT);
855
856 Query *queryObject = getQuery(id, true, target);
857 ASSERT(queryObject);
858
859 return queryObject->queryCounter();
860}
861
862void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
863{
864 switch (pname)
865 {
866 case GL_CURRENT_QUERY_EXT:
867 params[0] = getState().getActiveQueryId(target);
868 break;
869 case GL_QUERY_COUNTER_BITS_EXT:
870 switch (target)
871 {
872 case GL_TIME_ELAPSED_EXT:
873 params[0] = getExtensions().queryCounterBitsTimeElapsed;
874 break;
875 case GL_TIMESTAMP_EXT:
876 params[0] = getExtensions().queryCounterBitsTimestamp;
877 break;
878 default:
879 UNREACHABLE();
880 params[0] = 0;
881 break;
882 }
883 break;
884 default:
885 UNREACHABLE();
886 return;
887 }
888}
889
890Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
891{
892 return GetQueryObjectParameter(this, id, pname, params);
893}
894
895Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
896{
897 return GetQueryObjectParameter(this, id, pname, params);
898}
899
900Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
901{
902 return GetQueryObjectParameter(this, id, pname, params);
903}
904
905Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
906{
907 return GetQueryObjectParameter(this, id, pname, params);
908}
909
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500910Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000911{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500912 auto framebufferIt = mFramebufferMap.find(handle);
913 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000914}
915
Jamie Madill33dc8432013-07-26 11:55:05 -0400916FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000917{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500918 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000919
Jamie Madill33dc8432013-07-26 11:55:05 -0400920 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000921 {
922 return NULL;
923 }
924 else
925 {
926 return fence->second;
927 }
928}
929
930Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
931{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500932 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933
934 if (query == mQueryMap.end())
935 {
936 return NULL;
937 }
938 else
939 {
940 if (!query->second && create)
941 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700942 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000943 query->second->addRef();
944 }
945 return query->second;
946 }
947}
948
Geoff Lang70d0f492015-12-10 17:45:46 -0500949Query *Context::getQuery(GLuint handle) const
950{
951 auto iter = mQueryMap.find(handle);
952 return (iter != mQueryMap.end()) ? iter->second : nullptr;
953}
954
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500955Texture *Context::getTargetTexture(GLenum target) const
956{
Geoff Lang691e58c2014-12-19 17:03:25 -0500957 ASSERT(ValidTextureTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500958 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000959}
960
Geoff Lang76b10c92014-09-05 16:28:14 -0400961Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500963 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000964}
965
Geoff Lang492a7e42014-11-05 13:27:06 -0500966Compiler *Context::getCompiler() const
967{
968 return mCompiler;
969}
970
Jamie Madill893ab082014-05-16 16:56:10 -0400971void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000972{
973 switch (pname)
974 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000975 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000976 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400978 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400979 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981}
982
Jamie Madill893ab082014-05-16 16:56:10 -0400983void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
Shannon Woods53a94a82014-06-24 15:20:36 -0400985 // Queries about context capabilities and maximums are answered by Context.
986 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987 switch (pname)
988 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400990 params[0] = mCaps.minAliasedLineWidth;
991 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992 break;
993 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400994 params[0] = mCaps.minAliasedPointSize;
995 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000997 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400998 ASSERT(mExtensions.textureFilterAnisotropic);
999 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001000 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001001 case GL_MAX_TEXTURE_LOD_BIAS:
1002 *params = mCaps.maxLODBias;
1003 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001005 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001006 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008}
1009
Jamie Madill893ab082014-05-16 16:56:10 -04001010void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001011{
Shannon Woods53a94a82014-06-24 15:20:36 -04001012 // Queries about context capabilities and maximums are answered by Context.
1013 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001014
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001015 switch (pname)
1016 {
Geoff Lang301d1612014-07-09 10:34:37 -04001017 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1018 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1019 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001020 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1021 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1022 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001023 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1024 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1025 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001026 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001027 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1028 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1029 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001030 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001031 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001032 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1033 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1034 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1035 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001036 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1037 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001038 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1039 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001040 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001041 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1042 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1043 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1044 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001045 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1046 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001047 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1048 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001049 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1050 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1051 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001052 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1053 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1054 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001055 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001056 case GL_MAX_VIEWPORT_DIMS:
1057 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001058 params[0] = mCaps.maxViewportWidth;
1059 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001060 }
1061 break;
1062 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001063 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001064 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001065 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1066 *params = mResetStrategy;
1067 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001068 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001069 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001071 case GL_SHADER_BINARY_FORMATS:
1072 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1073 break;
1074 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001075 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001076 break;
1077 case GL_PROGRAM_BINARY_FORMATS:
1078 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001080 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001081 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001082 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001083
1084 // GL_KHR_debug
1085 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1086 *params = mExtensions.maxDebugMessageLength;
1087 break;
1088 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1089 *params = mExtensions.maxDebugLoggedMessages;
1090 break;
1091 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1092 *params = mExtensions.maxDebugGroupStackDepth;
1093 break;
1094 case GL_MAX_LABEL_LENGTH:
1095 *params = mExtensions.maxLabelLength;
1096 break;
1097
Ian Ewell53f59f42016-01-28 17:36:55 -05001098 // GL_EXT_disjoint_timer_query
1099 case GL_GPU_DISJOINT_EXT:
1100 *params = mRenderer->getGPUDisjoint();
1101 break;
1102
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001104 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001105 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001107}
1108
Jamie Madill893ab082014-05-16 16:56:10 -04001109void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001110{
Shannon Woods53a94a82014-06-24 15:20:36 -04001111 // Queries about context capabilities and maximums are answered by Context.
1112 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001113 switch (pname)
1114 {
1115 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001116 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001117 break;
1118 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001119 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001120 break;
1121 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001122 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001123 break;
1124 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001125 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001126 break;
1127 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001128 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001129 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001130
1131 // GL_EXT_disjoint_timer_query
1132 case GL_TIMESTAMP_EXT:
1133 *params = mRenderer->getTimestamp();
1134 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001136 UNREACHABLE();
1137 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001138 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001139}
1140
Geoff Lang70d0f492015-12-10 17:45:46 -05001141void Context::getPointerv(GLenum pname, void **params) const
1142{
1143 mState.getPointerv(pname, params);
1144}
1145
Shannon Woods1b2fb852013-08-19 14:28:48 -04001146bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1147{
Shannon Woods53a94a82014-06-24 15:20:36 -04001148 // Queries about context capabilities and maximums are answered by Context.
1149 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001150 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001151 // mere passthrough.
1152 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001153}
1154
1155bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1156{
Shannon Woods53a94a82014-06-24 15:20:36 -04001157 // Queries about context capabilities and maximums are answered by Context.
1158 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001159 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001160 // mere passthrough.
1161 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001162}
1163
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1165{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001166 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1167 {
1168 *type = GL_INT;
1169 *numParams = 1;
1170 return true;
1171 }
1172
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001173 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1174 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1175 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001176 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1178 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1179 // application.
1180 switch (pname)
1181 {
1182 case GL_COMPRESSED_TEXTURE_FORMATS:
1183 {
1184 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001185 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001186 }
1187 return true;
1188 case GL_PROGRAM_BINARY_FORMATS_OES:
1189 {
1190 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001191 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001192 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001193 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194 case GL_SHADER_BINARY_FORMATS:
1195 {
1196 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001197 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001198 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001199 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001200
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001201 case GL_MAX_VERTEX_ATTRIBS:
1202 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1203 case GL_MAX_VARYING_VECTORS:
1204 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1205 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1206 case GL_MAX_TEXTURE_IMAGE_UNITS:
1207 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1208 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001209 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001210 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211 case GL_NUM_SHADER_BINARY_FORMATS:
1212 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1213 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001214 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1215 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1216 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217 case GL_RENDERBUFFER_BINDING:
1218 case GL_CURRENT_PROGRAM:
1219 case GL_PACK_ALIGNMENT:
1220 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1221 case GL_UNPACK_ALIGNMENT:
1222 case GL_GENERATE_MIPMAP_HINT:
1223 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1224 case GL_RED_BITS:
1225 case GL_GREEN_BITS:
1226 case GL_BLUE_BITS:
1227 case GL_ALPHA_BITS:
1228 case GL_DEPTH_BITS:
1229 case GL_STENCIL_BITS:
1230 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1231 case GL_CULL_FACE_MODE:
1232 case GL_FRONT_FACE:
1233 case GL_ACTIVE_TEXTURE:
1234 case GL_STENCIL_FUNC:
1235 case GL_STENCIL_VALUE_MASK:
1236 case GL_STENCIL_REF:
1237 case GL_STENCIL_FAIL:
1238 case GL_STENCIL_PASS_DEPTH_FAIL:
1239 case GL_STENCIL_PASS_DEPTH_PASS:
1240 case GL_STENCIL_BACK_FUNC:
1241 case GL_STENCIL_BACK_VALUE_MASK:
1242 case GL_STENCIL_BACK_REF:
1243 case GL_STENCIL_BACK_FAIL:
1244 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1245 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1246 case GL_DEPTH_FUNC:
1247 case GL_BLEND_SRC_RGB:
1248 case GL_BLEND_SRC_ALPHA:
1249 case GL_BLEND_DST_RGB:
1250 case GL_BLEND_DST_ALPHA:
1251 case GL_BLEND_EQUATION_RGB:
1252 case GL_BLEND_EQUATION_ALPHA:
1253 case GL_STENCIL_WRITEMASK:
1254 case GL_STENCIL_BACK_WRITEMASK:
1255 case GL_STENCIL_CLEAR_VALUE:
1256 case GL_SUBPIXEL_BITS:
1257 case GL_MAX_TEXTURE_SIZE:
1258 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1259 case GL_SAMPLE_BUFFERS:
1260 case GL_SAMPLES:
1261 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1262 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1263 case GL_TEXTURE_BINDING_2D:
1264 case GL_TEXTURE_BINDING_CUBE_MAP:
1265 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1266 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 {
1268 *type = GL_INT;
1269 *numParams = 1;
1270 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001271 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001272 case GL_MAX_SAMPLES_ANGLE:
1273 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001274 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001275 {
1276 *type = GL_INT;
1277 *numParams = 1;
1278 }
1279 else
1280 {
1281 return false;
1282 }
1283 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001284 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285 case GL_MAX_VIEWPORT_DIMS:
1286 {
1287 *type = GL_INT;
1288 *numParams = 2;
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_VIEWPORT:
1292 case GL_SCISSOR_BOX:
1293 {
1294 *type = GL_INT;
1295 *numParams = 4;
1296 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001297 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298 case GL_SHADER_COMPILER:
1299 case GL_SAMPLE_COVERAGE_INVERT:
1300 case GL_DEPTH_WRITEMASK:
1301 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1302 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1303 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1304 case GL_SAMPLE_COVERAGE:
1305 case GL_SCISSOR_TEST:
1306 case GL_STENCIL_TEST:
1307 case GL_DEPTH_TEST:
1308 case GL_BLEND:
1309 case GL_DITHER:
1310 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1311 {
1312 *type = GL_BOOL;
1313 *numParams = 1;
1314 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001315 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 case GL_COLOR_WRITEMASK:
1317 {
1318 *type = GL_BOOL;
1319 *numParams = 4;
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_POLYGON_OFFSET_FACTOR:
1323 case GL_POLYGON_OFFSET_UNITS:
1324 case GL_SAMPLE_COVERAGE_VALUE:
1325 case GL_DEPTH_CLEAR_VALUE:
1326 case GL_LINE_WIDTH:
1327 {
1328 *type = GL_FLOAT;
1329 *numParams = 1;
1330 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001331 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 case GL_ALIASED_LINE_WIDTH_RANGE:
1333 case GL_ALIASED_POINT_SIZE_RANGE:
1334 case GL_DEPTH_RANGE:
1335 {
1336 *type = GL_FLOAT;
1337 *numParams = 2;
1338 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001339 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001340 case GL_COLOR_CLEAR_VALUE:
1341 case GL_BLEND_COLOR:
1342 {
1343 *type = GL_FLOAT;
1344 *numParams = 4;
1345 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001346 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001347 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001348 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001349 {
1350 return false;
1351 }
1352 *type = GL_FLOAT;
1353 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001354 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001355 case GL_TIMESTAMP_EXT:
1356 if (!mExtensions.disjointTimerQuery)
1357 {
1358 return false;
1359 }
1360 *type = GL_INT_64_ANGLEX;
1361 *numParams = 1;
1362 return true;
1363 case GL_GPU_DISJOINT_EXT:
1364 if (!mExtensions.disjointTimerQuery)
1365 {
1366 return false;
1367 }
1368 *type = GL_INT;
1369 *numParams = 1;
1370 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001371 }
1372
Geoff Lang70d0f492015-12-10 17:45:46 -05001373 if (mExtensions.debug)
1374 {
1375 switch (pname)
1376 {
1377 case GL_DEBUG_LOGGED_MESSAGES:
1378 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1379 case GL_DEBUG_GROUP_STACK_DEPTH:
1380 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1381 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1382 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1383 case GL_MAX_LABEL_LENGTH:
1384 *type = GL_INT;
1385 *numParams = 1;
1386 return true;
1387
1388 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1389 case GL_DEBUG_OUTPUT:
1390 *type = GL_BOOL;
1391 *numParams = 1;
1392 return true;
1393 }
1394 }
1395
Austin Kinrossbc781f32015-10-26 09:27:38 -07001396 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1397 switch (pname)
1398 {
1399 case GL_PACK_ROW_LENGTH:
1400 case GL_PACK_SKIP_ROWS:
1401 case GL_PACK_SKIP_PIXELS:
1402 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1403 {
1404 return false;
1405 }
1406 *type = GL_INT;
1407 *numParams = 1;
1408 return true;
1409 case GL_UNPACK_ROW_LENGTH:
1410 case GL_UNPACK_SKIP_ROWS:
1411 case GL_UNPACK_SKIP_PIXELS:
1412 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1413 {
1414 return false;
1415 }
1416 *type = GL_INT;
1417 *numParams = 1;
1418 return true;
1419 case GL_VERTEX_ARRAY_BINDING:
1420 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1421 {
1422 return false;
1423 }
1424 *type = GL_INT;
1425 *numParams = 1;
1426 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001427 case GL_PIXEL_PACK_BUFFER_BINDING:
1428 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1429 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1430 {
1431 return false;
1432 }
1433 *type = GL_INT;
1434 *numParams = 1;
1435 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001436 }
1437
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001438 if (mClientVersion < 3)
1439 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001440 return false;
1441 }
1442
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001443 // Check for ES3.0+ parameter names
1444 switch (pname)
1445 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001446 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1447 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001448 case GL_UNIFORM_BUFFER_BINDING:
1449 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001450 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001451 case GL_COPY_READ_BUFFER_BINDING:
1452 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001453 case GL_SAMPLER_BINDING:
1454 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001455 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001456 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001457 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001458 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001459 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1460 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1461 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001462 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1463 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001464 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001465 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1466 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001467 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1468 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001469 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001470 case GL_MAJOR_VERSION:
1471 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001472 case GL_MAX_ELEMENTS_INDICES:
1473 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001474 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001475 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001476 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001477 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001478 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001479 {
1480 *type = GL_INT;
1481 *numParams = 1;
1482 }
1483 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001484
1485 case GL_MAX_ELEMENT_INDEX:
1486 case GL_MAX_UNIFORM_BLOCK_SIZE:
1487 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1488 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1489 case GL_MAX_SERVER_WAIT_TIMEOUT:
1490 {
1491 *type = GL_INT_64_ANGLEX;
1492 *numParams = 1;
1493 }
1494 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001495
1496 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001497 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001498 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001499 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001500 {
1501 *type = GL_BOOL;
1502 *numParams = 1;
1503 }
1504 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001505
1506 case GL_MAX_TEXTURE_LOD_BIAS:
1507 {
1508 *type = GL_FLOAT;
1509 *numParams = 1;
1510 }
1511 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001512 }
1513
1514 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001515}
1516
Shannon Woods1b2fb852013-08-19 14:28:48 -04001517bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1518{
1519 if (mClientVersion < 3)
1520 {
1521 return false;
1522 }
1523
1524 switch (target)
1525 {
1526 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1527 case GL_UNIFORM_BUFFER_BINDING:
1528 {
1529 *type = GL_INT;
1530 *numParams = 1;
1531 }
1532 return true;
1533 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1534 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1535 case GL_UNIFORM_BUFFER_START:
1536 case GL_UNIFORM_BUFFER_SIZE:
1537 {
1538 *type = GL_INT_64_ANGLEX;
1539 *numParams = 1;
1540 }
1541 }
1542
1543 return false;
1544}
1545
Geoff Langf6db0982015-08-25 13:04:00 -04001546Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001547{
Jamie Madill1b94d432015-08-07 13:23:23 -04001548 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001549 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001550 if (error.isError())
1551 {
1552 return error;
1553 }
1554
Geoff Langf6db0982015-08-25 13:04:00 -04001555 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001556
1557 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001558}
1559
Geoff Langf6db0982015-08-25 13:04:00 -04001560Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1561{
1562 syncRendererState();
1563 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1564 if (error.isError())
1565 {
1566 return error;
1567 }
1568
1569 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1570
1571 return Error(GL_NO_ERROR);
1572}
1573
1574Error Context::drawElements(GLenum mode,
1575 GLsizei count,
1576 GLenum type,
1577 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001578 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001579{
Jamie Madill1b94d432015-08-07 13:23:23 -04001580 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001581 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1582}
1583
1584Error Context::drawElementsInstanced(GLenum mode,
1585 GLsizei count,
1586 GLenum type,
1587 const GLvoid *indices,
1588 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001589 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001590{
1591 syncRendererState();
1592 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1593 indexRange);
1594}
1595
1596Error Context::drawRangeElements(GLenum mode,
1597 GLuint start,
1598 GLuint end,
1599 GLsizei count,
1600 GLenum type,
1601 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001602 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001603{
1604 syncRendererState();
1605 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1606 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607}
1608
Geoff Lang129753a2015-01-09 16:52:09 -05001609Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001610{
Geoff Lang129753a2015-01-09 16:52:09 -05001611 return mRenderer->flush();
1612}
1613
1614Error Context::finish()
1615{
1616 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001617}
1618
Austin Kinross6ee1e782015-05-29 17:05:37 -07001619void Context::insertEventMarker(GLsizei length, const char *marker)
1620{
1621 ASSERT(mRenderer);
1622 mRenderer->insertEventMarker(length, marker);
1623}
1624
1625void Context::pushGroupMarker(GLsizei length, const char *marker)
1626{
1627 ASSERT(mRenderer);
1628 mRenderer->pushGroupMarker(length, marker);
1629}
1630
1631void Context::popGroupMarker()
1632{
1633 ASSERT(mRenderer);
1634 mRenderer->popGroupMarker();
1635}
1636
Geoff Langd8605522016-04-13 10:19:12 -04001637void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1638{
1639 Program *programObject = getProgram(program);
1640 ASSERT(programObject);
1641
1642 programObject->bindUniformLocation(location, name);
1643}
1644
Geoff Langda5777c2014-07-11 09:52:58 -04001645void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001646{
Geoff Langda5777c2014-07-11 09:52:58 -04001647 if (error.isError())
1648 {
1649 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001650
1651 if (!error.getMessage().empty())
1652 {
1653 auto &debug = mState.getDebug();
1654 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1655 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1656 }
Geoff Langda5777c2014-07-11 09:52:58 -04001657 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001658}
1659
1660// Get one of the recorded errors and clear its flag, if any.
1661// [OpenGL ES 2.0.24] section 2.5 page 13.
1662GLenum Context::getError()
1663{
Geoff Langda5777c2014-07-11 09:52:58 -04001664 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001665 {
Geoff Langda5777c2014-07-11 09:52:58 -04001666 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001667 }
Geoff Langda5777c2014-07-11 09:52:58 -04001668 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001669 {
Geoff Langda5777c2014-07-11 09:52:58 -04001670 GLenum error = *mErrors.begin();
1671 mErrors.erase(mErrors.begin());
1672 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001674}
1675
1676GLenum Context::getResetStatus()
1677{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001678 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001679 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001680 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001681 // mResetStatus will be set by the markContextLost callback
1682 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001683 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001684 {
1685 mRenderer->notifyDeviceLost();
1686 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687 }
1688
1689 GLenum status = mResetStatus;
1690
1691 if (mResetStatus != GL_NO_ERROR)
1692 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001693 ASSERT(mContextLost);
1694
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001695 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001696 {
1697 mResetStatus = GL_NO_ERROR;
1698 }
1699 }
Jamie Madill893ab082014-05-16 16:56:10 -04001700
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001701 return status;
1702}
1703
1704bool Context::isResetNotificationEnabled()
1705{
1706 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1707}
1708
Corentin Walleze3b10e82015-05-20 11:06:25 -04001709const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001710{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001711 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001712}
1713
1714EGLenum Context::getClientType() const
1715{
1716 return mClientType;
1717}
1718
1719EGLenum Context::getRenderBuffer() const
1720{
Corentin Wallez37c39792015-08-20 14:19:46 -04001721 auto framebufferIt = mFramebufferMap.find(0);
1722 if (framebufferIt != mFramebufferMap.end())
1723 {
1724 const Framebuffer *framebuffer = framebufferIt->second;
1725 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1726
1727 ASSERT(backAttachment != nullptr);
1728 return backAttachment->getSurface()->getRenderBuffer();
1729 }
1730 else
1731 {
1732 return EGL_NONE;
1733 }
Régis Fénéon83107972015-02-05 12:57:44 +01001734}
1735
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001736VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001737{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001738 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001739 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1740 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001741 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001742 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1743 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001744 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001745
1746 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001747}
1748
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001749TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001750{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001751 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001752 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1753 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001754 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001755 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1756 transformFeedback->addRef();
1757 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001758 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001759
1760 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001761}
1762
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001763Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1764{
1765 // Can be called from Bind without a prior call to Gen.
1766 auto framebufferIt = mFramebufferMap.find(framebuffer);
1767 bool neverCreated = framebufferIt == mFramebufferMap.end();
1768 if (neverCreated || framebufferIt->second == nullptr)
1769 {
1770 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1771 if (neverCreated)
1772 {
1773 mFramebufferHandleAllocator.reserve(framebuffer);
1774 mFramebufferMap[framebuffer] = newFBO;
1775 return newFBO;
1776 }
1777
1778 framebufferIt->second = newFBO;
1779 }
1780
1781 return framebufferIt->second;
1782}
1783
Geoff Lang36167ab2015-12-07 10:27:14 -05001784bool Context::isVertexArrayGenerated(GLuint vertexArray)
1785{
1786 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1787}
1788
1789bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1790{
1791 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1792}
1793
Shannon Woods53a94a82014-06-24 15:20:36 -04001794void Context::detachTexture(GLuint texture)
1795{
1796 // Simple pass-through to State's detachTexture method, as textures do not require
1797 // allocation map management either here or in the resource manager at detach time.
1798 // Zero textures are held by the Context, and we don't attempt to request them from
1799 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001800 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001801}
1802
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001803void Context::detachBuffer(GLuint buffer)
1804{
Yuly Novikov5807a532015-12-03 13:01:22 -05001805 // Simple pass-through to State's detachBuffer method, since
1806 // only buffer attachments to container objects that are bound to the current context
1807 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001808
Yuly Novikov5807a532015-12-03 13:01:22 -05001809 // [OpenGL ES 3.2] section 5.1.2 page 45:
1810 // Attachments to unbound container objects, such as
1811 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1812 // are not affected and continue to act as references on the deleted object
1813 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001814}
1815
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001816void Context::detachFramebuffer(GLuint framebuffer)
1817{
Shannon Woods53a94a82014-06-24 15:20:36 -04001818 // Framebuffer detachment is handled by Context, because 0 is a valid
1819 // Framebuffer object, and a pointer to it must be passed from Context
1820 // to State at binding time.
1821
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001822 // [OpenGL ES 2.0.24] section 4.4 page 107:
1823 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1824 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1825
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001826 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001827 {
1828 bindReadFramebuffer(0);
1829 }
1830
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001831 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832 {
1833 bindDrawFramebuffer(0);
1834 }
1835}
1836
1837void Context::detachRenderbuffer(GLuint renderbuffer)
1838{
Shannon Woods53a94a82014-06-24 15:20:36 -04001839 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001840}
1841
Jamie Madill57a89722013-07-02 11:57:03 -04001842void Context::detachVertexArray(GLuint vertexArray)
1843{
Jamie Madill77a72f62015-04-14 11:18:32 -04001844 // Vertex array detachment is handled by Context, because 0 is a valid
1845 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001846 // binding time.
1847
Jamie Madill57a89722013-07-02 11:57:03 -04001848 // [OpenGL ES 3.0.2] section 2.10 page 43:
1849 // If a vertex array object that is currently bound is deleted, the binding
1850 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001851 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001852 {
1853 bindVertexArray(0);
1854 }
1855}
1856
Geoff Langc8058452014-02-03 12:04:11 -05001857void Context::detachTransformFeedback(GLuint transformFeedback)
1858{
Shannon Woods53a94a82014-06-24 15:20:36 -04001859 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001860}
1861
Jamie Madilldc356042013-07-19 16:36:57 -04001862void Context::detachSampler(GLuint sampler)
1863{
Shannon Woods53a94a82014-06-24 15:20:36 -04001864 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001865}
1866
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001867void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1868{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001869 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001870}
1871
Jamie Madille29d1672013-07-19 16:36:57 -04001872void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1873{
1874 mResourceManager->checkSamplerAllocation(sampler);
1875
1876 Sampler *samplerObject = getSampler(sampler);
1877 ASSERT(samplerObject);
1878
Geoff Lang69cce582015-09-17 13:20:36 -04001879 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001880 switch (pname)
1881 {
Geoff Lang69cce582015-09-17 13:20:36 -04001882 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1883 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1884 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1885 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1886 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1887 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1888 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1889 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1890 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1891 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1892 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001893 }
Geoff Lang69cce582015-09-17 13:20:36 -04001894 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001895}
1896
1897void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1898{
1899 mResourceManager->checkSamplerAllocation(sampler);
1900
1901 Sampler *samplerObject = getSampler(sampler);
1902 ASSERT(samplerObject);
1903
Geoff Lang69cce582015-09-17 13:20:36 -04001904 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001905 switch (pname)
1906 {
Geoff Lang69cce582015-09-17 13:20:36 -04001907 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1908 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1909 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1910 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1911 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1912 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1913 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1914 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1915 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1916 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1917 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001918 }
Geoff Lang69cce582015-09-17 13:20:36 -04001919 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001920}
1921
Jamie Madill9675b802013-07-19 16:36:59 -04001922GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1923{
1924 mResourceManager->checkSamplerAllocation(sampler);
1925
1926 Sampler *samplerObject = getSampler(sampler);
1927 ASSERT(samplerObject);
1928
Geoff Lang69cce582015-09-17 13:20:36 -04001929 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001930 switch (pname)
1931 {
Geoff Lang69cce582015-09-17 13:20:36 -04001932 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1933 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1934 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1935 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1936 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1937 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001938 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1939 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001940 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1941 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1942 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001943 }
Geoff Lang69cce582015-09-17 13:20:36 -04001944 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001945}
1946
1947GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1948{
1949 mResourceManager->checkSamplerAllocation(sampler);
1950
1951 Sampler *samplerObject = getSampler(sampler);
1952 ASSERT(samplerObject);
1953
Geoff Lang69cce582015-09-17 13:20:36 -04001954 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001955 switch (pname)
1956 {
Geoff Lang69cce582015-09-17 13:20:36 -04001957 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1958 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1959 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1960 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1961 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1962 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1963 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1964 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1965 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1966 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1967 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001968 }
Geoff Lang69cce582015-09-17 13:20:36 -04001969 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001970}
1971
Olli Etuahof0fee072016-03-30 15:11:58 +03001972void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1973{
1974 gl::Program *programObject = getProgram(program);
1975 ASSERT(programObject != nullptr);
1976
1977 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1978 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1979}
1980
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001981void Context::initRendererString()
1982{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001983 std::ostringstream rendererString;
1984 rendererString << "ANGLE (";
1985 rendererString << mRenderer->getRendererDescription();
1986 rendererString << ")";
1987
Geoff Langcec35902014-04-16 10:52:36 -04001988 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001989}
1990
Geoff Langc0b9ef42014-07-02 10:02:37 -04001991const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001992{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001993 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001994}
1995
Geoff Langcec35902014-04-16 10:52:36 -04001996void Context::initExtensionStrings()
1997{
Geoff Lang493daf52014-07-03 13:38:44 -04001998 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001999
Geoff Langc0b9ef42014-07-02 10:02:37 -04002000 std::ostringstream combinedStringStream;
2001 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2002 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002003}
2004
Geoff Langc0b9ef42014-07-02 10:02:37 -04002005const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002006{
2007 return mExtensionString;
2008}
2009
Geoff Langc0b9ef42014-07-02 10:02:37 -04002010const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002011{
2012 return mExtensionStrings[idx];
2013}
2014
2015size_t Context::getExtensionStringCount() const
2016{
2017 return mExtensionStrings.size();
2018}
2019
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002020void Context::beginTransformFeedback(GLenum primitiveMode)
2021{
2022 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2023 ASSERT(transformFeedback != nullptr);
2024 ASSERT(!transformFeedback->isPaused());
2025
2026 transformFeedback->begin(primitiveMode, getState().getProgram());
2027}
2028
2029bool Context::hasActiveTransformFeedback(GLuint program) const
2030{
2031 for (auto pair : mTransformFeedbackMap)
2032 {
2033 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2034 {
2035 return true;
2036 }
2037 }
2038 return false;
2039}
2040
Geoff Lang493daf52014-07-03 13:38:44 -04002041void Context::initCaps(GLuint clientVersion)
2042{
2043 mCaps = mRenderer->getRendererCaps();
2044
2045 mExtensions = mRenderer->getRendererExtensions();
2046
Austin Kinross02df7962015-07-01 10:03:42 -07002047 mLimitations = mRenderer->getRendererLimitations();
2048
Geoff Lang493daf52014-07-03 13:38:44 -04002049 if (clientVersion < 3)
2050 {
2051 // Disable ES3+ extensions
2052 mExtensions.colorBufferFloat = false;
2053 }
2054
2055 if (clientVersion > 2)
2056 {
2057 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2058 //mExtensions.sRGB = false;
2059 }
2060
Geoff Lang70d0f492015-12-10 17:45:46 -05002061 // Explicitly enable GL_KHR_debug
2062 mExtensions.debug = true;
2063 mExtensions.maxDebugMessageLength = 1024;
2064 mExtensions.maxDebugLoggedMessages = 1024;
2065 mExtensions.maxDebugGroupStackDepth = 1024;
2066 mExtensions.maxLabelLength = 1024;
2067
Geoff Lang301d1612014-07-09 10:34:37 -04002068 // Apply implementation limits
2069 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002070 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2071 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2072
2073 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002074
Geoff Lang900013c2014-07-07 11:32:19 -04002075 mCaps.compressedTextureFormats.clear();
2076
Geoff Lang493daf52014-07-03 13:38:44 -04002077 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2078 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2079 {
2080 GLenum format = i->first;
2081 TextureCaps formatCaps = i->second;
2082
Geoff Lang5d601382014-07-22 15:14:06 -04002083 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002084
Geoff Lang0d8b7242015-09-09 14:56:53 -04002085 // Update the format caps based on the client version and extensions.
2086 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2087 // ES3.
2088 formatCaps.texturable =
2089 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2090 formatCaps.renderable =
2091 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2092 formatCaps.filterable =
2093 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002094
2095 // OpenGL ES does not support multisampling with integer formats
2096 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002097 {
Geoff Langd87878e2014-09-19 15:42:59 -04002098 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002099 }
Geoff Langd87878e2014-09-19 15:42:59 -04002100
2101 if (formatCaps.texturable && formatInfo.compressed)
2102 {
2103 mCaps.compressedTextureFormats.push_back(format);
2104 }
2105
2106 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002107 }
2108}
2109
Jamie Madill1b94d432015-08-07 13:23:23 -04002110void Context::syncRendererState()
2111{
2112 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002113 mRenderer->syncState(mState, dirtyBits);
2114 mState.clearDirtyBits();
2115 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002116}
2117
Jamie Madillad9f24e2016-02-12 09:27:24 -05002118void Context::syncRendererState(const State::DirtyBits &bitMask,
2119 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002120{
2121 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002122 mRenderer->syncState(mState, dirtyBits);
2123 mState.clearDirtyBits(dirtyBits);
2124
Jamie Madillad9f24e2016-02-12 09:27:24 -05002125 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002126}
Jamie Madillc29968b2016-01-20 11:17:23 -05002127
2128void Context::blitFramebuffer(GLint srcX0,
2129 GLint srcY0,
2130 GLint srcX1,
2131 GLint srcY1,
2132 GLint dstX0,
2133 GLint dstY0,
2134 GLint dstX1,
2135 GLint dstY1,
2136 GLbitfield mask,
2137 GLenum filter)
2138{
2139 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2140 ASSERT(readFramebuffer);
2141
2142 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2143 ASSERT(drawFramebuffer);
2144
2145 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2146 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2147
Jamie Madillad9f24e2016-02-12 09:27:24 -05002148 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002149
2150 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2151 if (error.isError())
2152 {
2153 recordError(error);
2154 return;
2155 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002156}
Jamie Madillc29968b2016-01-20 11:17:23 -05002157
2158void Context::clear(GLbitfield mask)
2159{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002160 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002161
2162 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2163 if (error.isError())
2164 {
2165 recordError(error);
2166 }
2167}
2168
2169void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2170{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002171 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002172
2173 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2174 if (error.isError())
2175 {
2176 recordError(error);
2177 }
2178}
2179
2180void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2181{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002182 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002183
2184 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2185 if (error.isError())
2186 {
2187 recordError(error);
2188 }
2189}
2190
2191void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2192{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002193 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002194
2195 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2196 if (error.isError())
2197 {
2198 recordError(error);
2199 }
2200}
2201
2202void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2203{
2204 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2205 ASSERT(framebufferObject);
2206
2207 // If a buffer is not present, the clear has no effect
2208 if (framebufferObject->getDepthbuffer() == nullptr &&
2209 framebufferObject->getStencilbuffer() == nullptr)
2210 {
2211 return;
2212 }
2213
Jamie Madillad9f24e2016-02-12 09:27:24 -05002214 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002215
2216 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2217 if (error.isError())
2218 {
2219 recordError(error);
2220 }
2221}
2222
2223void Context::readPixels(GLint x,
2224 GLint y,
2225 GLsizei width,
2226 GLsizei height,
2227 GLenum format,
2228 GLenum type,
2229 GLvoid *pixels)
2230{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002231 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002232
2233 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2234 ASSERT(framebufferObject);
2235
2236 Rectangle area(x, y, width, height);
2237 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2238 if (error.isError())
2239 {
2240 recordError(error);
2241 }
2242}
2243
2244void Context::copyTexImage2D(GLenum target,
2245 GLint level,
2246 GLenum internalformat,
2247 GLint x,
2248 GLint y,
2249 GLsizei width,
2250 GLsizei height,
2251 GLint border)
2252{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002253 // Only sync the read FBO
2254 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2255
Jamie Madillc29968b2016-01-20 11:17:23 -05002256 Rectangle sourceArea(x, y, width, height);
2257
2258 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2259 Texture *texture =
2260 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2261 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2262 if (error.isError())
2263 {
2264 recordError(error);
2265 }
2266}
2267
2268void Context::copyTexSubImage2D(GLenum target,
2269 GLint level,
2270 GLint xoffset,
2271 GLint yoffset,
2272 GLint x,
2273 GLint y,
2274 GLsizei width,
2275 GLsizei height)
2276{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002277 // Only sync the read FBO
2278 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2279
Jamie Madillc29968b2016-01-20 11:17:23 -05002280 Offset destOffset(xoffset, yoffset, 0);
2281 Rectangle sourceArea(x, y, width, height);
2282
2283 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2284 Texture *texture =
2285 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2286 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2287 if (error.isError())
2288 {
2289 recordError(error);
2290 }
2291}
2292
2293void Context::copyTexSubImage3D(GLenum target,
2294 GLint level,
2295 GLint xoffset,
2296 GLint yoffset,
2297 GLint zoffset,
2298 GLint x,
2299 GLint y,
2300 GLsizei width,
2301 GLsizei height)
2302{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002303 // Only sync the read FBO
2304 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2305
Jamie Madillc29968b2016-01-20 11:17:23 -05002306 Offset destOffset(xoffset, yoffset, zoffset);
2307 Rectangle sourceArea(x, y, width, height);
2308
2309 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2310 Texture *texture = getTargetTexture(target);
2311 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2312 if (error.isError())
2313 {
2314 recordError(error);
2315 }
2316}
2317
2318void Context::framebufferTexture2D(GLenum target,
2319 GLenum attachment,
2320 GLenum textarget,
2321 GLuint texture,
2322 GLint level)
2323{
2324 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2325 ASSERT(framebuffer);
2326
2327 if (texture != 0)
2328 {
2329 Texture *textureObj = getTexture(texture);
2330
2331 ImageIndex index = ImageIndex::MakeInvalid();
2332
2333 if (textarget == GL_TEXTURE_2D)
2334 {
2335 index = ImageIndex::Make2D(level);
2336 }
2337 else
2338 {
2339 ASSERT(IsCubeMapTextureTarget(textarget));
2340 index = ImageIndex::MakeCube(textarget, level);
2341 }
2342
2343 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2344 }
2345 else
2346 {
2347 framebuffer->resetAttachment(attachment);
2348 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002349
2350 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002351}
2352
2353void Context::framebufferRenderbuffer(GLenum target,
2354 GLenum attachment,
2355 GLenum renderbuffertarget,
2356 GLuint renderbuffer)
2357{
2358 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2359 ASSERT(framebuffer);
2360
2361 if (renderbuffer != 0)
2362 {
2363 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2364 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2365 renderbufferObject);
2366 }
2367 else
2368 {
2369 framebuffer->resetAttachment(attachment);
2370 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002371
2372 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002373}
2374
2375void Context::framebufferTextureLayer(GLenum target,
2376 GLenum attachment,
2377 GLuint texture,
2378 GLint level,
2379 GLint layer)
2380{
2381 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2382 ASSERT(framebuffer);
2383
2384 if (texture != 0)
2385 {
2386 Texture *textureObject = getTexture(texture);
2387
2388 ImageIndex index = ImageIndex::MakeInvalid();
2389
2390 if (textureObject->getTarget() == GL_TEXTURE_3D)
2391 {
2392 index = ImageIndex::Make3D(level, layer);
2393 }
2394 else
2395 {
2396 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2397 index = ImageIndex::Make2DArray(level, layer);
2398 }
2399
2400 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2401 }
2402 else
2403 {
2404 framebuffer->resetAttachment(attachment);
2405 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002406
2407 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002408}
2409
2410void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2411{
2412 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2413 ASSERT(framebuffer);
2414 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002415 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002416}
2417
2418void Context::readBuffer(GLenum mode)
2419{
2420 Framebuffer *readFBO = mState.getReadFramebuffer();
2421 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002422 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002423}
2424
2425void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2426{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002427 // Only sync the FBO
2428 mState.syncDirtyObject(target);
2429
Jamie Madillc29968b2016-01-20 11:17:23 -05002430 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2431 ASSERT(framebuffer);
2432
2433 // The specification isn't clear what should be done when the framebuffer isn't complete.
2434 // We leave it up to the framebuffer implementation to decide what to do.
2435 Error error = framebuffer->discard(numAttachments, attachments);
2436 if (error.isError())
2437 {
2438 recordError(error);
2439 }
2440}
2441
2442void Context::invalidateFramebuffer(GLenum target,
2443 GLsizei numAttachments,
2444 const GLenum *attachments)
2445{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002446 // Only sync the FBO
2447 mState.syncDirtyObject(target);
2448
Jamie Madillc29968b2016-01-20 11:17:23 -05002449 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2450 ASSERT(framebuffer);
2451
2452 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2453 {
2454 Error error = framebuffer->invalidate(numAttachments, attachments);
2455 if (error.isError())
2456 {
2457 recordError(error);
2458 return;
2459 }
2460 }
2461}
2462
2463void Context::invalidateSubFramebuffer(GLenum target,
2464 GLsizei numAttachments,
2465 const GLenum *attachments,
2466 GLint x,
2467 GLint y,
2468 GLsizei width,
2469 GLsizei height)
2470{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002471 // Only sync the FBO
2472 mState.syncDirtyObject(target);
2473
Jamie Madillc29968b2016-01-20 11:17:23 -05002474 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2475 ASSERT(framebuffer);
2476
2477 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2478 {
2479 Rectangle area(x, y, width, height);
2480 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2481 if (error.isError())
2482 {
2483 recordError(error);
2484 return;
2485 }
2486 }
2487}
2488
Jamie Madill73a84962016-02-12 09:27:23 -05002489void Context::texImage2D(GLenum target,
2490 GLint level,
2491 GLint internalformat,
2492 GLsizei width,
2493 GLsizei height,
2494 GLint border,
2495 GLenum format,
2496 GLenum type,
2497 const GLvoid *pixels)
2498{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002499 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002500
2501 Extents size(width, height, 1);
2502 Texture *texture =
2503 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2504 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2505 format, type, reinterpret_cast<const uint8_t *>(pixels));
2506 if (error.isError())
2507 {
2508 recordError(error);
2509 }
2510}
2511
2512void Context::texImage3D(GLenum target,
2513 GLint level,
2514 GLint internalformat,
2515 GLsizei width,
2516 GLsizei height,
2517 GLsizei depth,
2518 GLint border,
2519 GLenum format,
2520 GLenum type,
2521 const GLvoid *pixels)
2522{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002523 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002524
2525 Extents size(width, height, depth);
2526 Texture *texture = getTargetTexture(target);
2527 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2528 format, type, reinterpret_cast<const uint8_t *>(pixels));
2529 if (error.isError())
2530 {
2531 recordError(error);
2532 }
2533}
2534
2535void Context::texSubImage2D(GLenum target,
2536 GLint level,
2537 GLint xoffset,
2538 GLint yoffset,
2539 GLsizei width,
2540 GLsizei height,
2541 GLenum format,
2542 GLenum type,
2543 const GLvoid *pixels)
2544{
2545 // Zero sized uploads are valid but no-ops
2546 if (width == 0 || height == 0)
2547 {
2548 return;
2549 }
2550
Jamie Madillad9f24e2016-02-12 09:27:24 -05002551 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002552
2553 Box area(xoffset, yoffset, 0, width, height, 1);
2554 Texture *texture =
2555 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2556 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2557 reinterpret_cast<const uint8_t *>(pixels));
2558 if (error.isError())
2559 {
2560 recordError(error);
2561 }
2562}
2563
2564void Context::texSubImage3D(GLenum target,
2565 GLint level,
2566 GLint xoffset,
2567 GLint yoffset,
2568 GLint zoffset,
2569 GLsizei width,
2570 GLsizei height,
2571 GLsizei depth,
2572 GLenum format,
2573 GLenum type,
2574 const GLvoid *pixels)
2575{
2576 // Zero sized uploads are valid but no-ops
2577 if (width == 0 || height == 0 || depth == 0)
2578 {
2579 return;
2580 }
2581
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002583
2584 Box area(xoffset, yoffset, zoffset, width, height, depth);
2585 Texture *texture = getTargetTexture(target);
2586 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2587 reinterpret_cast<const uint8_t *>(pixels));
2588 if (error.isError())
2589 {
2590 recordError(error);
2591 }
2592}
2593
2594void Context::compressedTexImage2D(GLenum target,
2595 GLint level,
2596 GLenum internalformat,
2597 GLsizei width,
2598 GLsizei height,
2599 GLint border,
2600 GLsizei imageSize,
2601 const GLvoid *data)
2602{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002603 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002604
2605 Extents size(width, height, 1);
2606 Texture *texture =
2607 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2608 Error error =
2609 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2610 imageSize, reinterpret_cast<const uint8_t *>(data));
2611 if (error.isError())
2612 {
2613 recordError(error);
2614 }
2615}
2616
2617void Context::compressedTexImage3D(GLenum target,
2618 GLint level,
2619 GLenum internalformat,
2620 GLsizei width,
2621 GLsizei height,
2622 GLsizei depth,
2623 GLint border,
2624 GLsizei imageSize,
2625 const GLvoid *data)
2626{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002627 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002628
2629 Extents size(width, height, depth);
2630 Texture *texture = getTargetTexture(target);
2631 Error error =
2632 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2633 imageSize, reinterpret_cast<const uint8_t *>(data));
2634 if (error.isError())
2635 {
2636 recordError(error);
2637 }
2638}
2639
2640void Context::compressedTexSubImage2D(GLenum target,
2641 GLint level,
2642 GLint xoffset,
2643 GLint yoffset,
2644 GLsizei width,
2645 GLsizei height,
2646 GLenum format,
2647 GLsizei imageSize,
2648 const GLvoid *data)
2649{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002650 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002651
2652 Box area(xoffset, yoffset, 0, width, height, 1);
2653 Texture *texture =
2654 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2655 Error error =
2656 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2657 imageSize, reinterpret_cast<const uint8_t *>(data));
2658 if (error.isError())
2659 {
2660 recordError(error);
2661 }
2662}
2663
2664void Context::compressedTexSubImage3D(GLenum target,
2665 GLint level,
2666 GLint xoffset,
2667 GLint yoffset,
2668 GLint zoffset,
2669 GLsizei width,
2670 GLsizei height,
2671 GLsizei depth,
2672 GLenum format,
2673 GLsizei imageSize,
2674 const GLvoid *data)
2675{
2676 // Zero sized uploads are valid but no-ops
2677 if (width == 0 || height == 0)
2678 {
2679 return;
2680 }
2681
Jamie Madillad9f24e2016-02-12 09:27:24 -05002682 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002683
2684 Box area(xoffset, yoffset, zoffset, width, height, depth);
2685 Texture *texture = getTargetTexture(target);
2686 Error error =
2687 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2688 imageSize, reinterpret_cast<const uint8_t *>(data));
2689 if (error.isError())
2690 {
2691 recordError(error);
2692 }
2693}
2694
Olli Etuaho4f667482016-03-30 15:56:35 +03002695void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2696{
2697 Buffer *buffer = getState().getTargetBuffer(target);
2698 ASSERT(buffer);
2699
2700 if (!buffer->isMapped())
2701 {
2702 *params = nullptr;
2703 }
2704 else
2705 {
2706 *params = buffer->getMapPointer();
2707 }
2708}
2709
2710GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2711{
2712 Buffer *buffer = getState().getTargetBuffer(target);
2713 ASSERT(buffer);
2714
2715 Error error = buffer->map(access);
2716 if (error.isError())
2717 {
2718 recordError(error);
2719 return nullptr;
2720 }
2721
2722 return buffer->getMapPointer();
2723}
2724
2725GLboolean Context::unmapBuffer(GLenum target)
2726{
2727 Buffer *buffer = getState().getTargetBuffer(target);
2728 ASSERT(buffer);
2729
2730 GLboolean result;
2731 Error error = buffer->unmap(&result);
2732 if (error.isError())
2733 {
2734 recordError(error);
2735 return GL_FALSE;
2736 }
2737
2738 return result;
2739}
2740
2741GLvoid *Context::mapBufferRange(GLenum target,
2742 GLintptr offset,
2743 GLsizeiptr length,
2744 GLbitfield access)
2745{
2746 Buffer *buffer = getState().getTargetBuffer(target);
2747 ASSERT(buffer);
2748
2749 Error error = buffer->mapRange(offset, length, access);
2750 if (error.isError())
2751 {
2752 recordError(error);
2753 return nullptr;
2754 }
2755
2756 return buffer->getMapPointer();
2757}
2758
2759void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2760{
2761 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2762}
2763
Jamie Madillad9f24e2016-02-12 09:27:24 -05002764void Context::syncStateForReadPixels()
2765{
2766 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2767}
2768
2769void Context::syncStateForTexImage()
2770{
2771 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2772}
2773
2774void Context::syncStateForClear()
2775{
2776 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2777}
2778
2779void Context::syncStateForBlit()
2780{
2781 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2782}
2783
Jamie Madillc29968b2016-01-20 11:17:23 -05002784} // namespace gl