blob: dcb6b21bb1bf29f09157dff4634306c31aa32c5a [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
Geoff Lang691e58c2014-12-19 17:03:25 -0500175 Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 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
Geoff Lang691e58c2014-12-19 17:03:25 -0500178 Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 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
Geoff Lang691e58c2014-12-19 17:03:25 -0500184 Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 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
Geoff Lang691e58c2014-12-19 17:03:25 -0500187 Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 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 Langda5777c2014-07-11 09:52:58 -04001637void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001638{
Geoff Langda5777c2014-07-11 09:52:58 -04001639 if (error.isError())
1640 {
1641 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001642
1643 if (!error.getMessage().empty())
1644 {
1645 auto &debug = mState.getDebug();
1646 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1647 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1648 }
Geoff Langda5777c2014-07-11 09:52:58 -04001649 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001650}
1651
1652// Get one of the recorded errors and clear its flag, if any.
1653// [OpenGL ES 2.0.24] section 2.5 page 13.
1654GLenum Context::getError()
1655{
Geoff Langda5777c2014-07-11 09:52:58 -04001656 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001657 {
Geoff Langda5777c2014-07-11 09:52:58 -04001658 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659 }
Geoff Langda5777c2014-07-11 09:52:58 -04001660 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661 {
Geoff Langda5777c2014-07-11 09:52:58 -04001662 GLenum error = *mErrors.begin();
1663 mErrors.erase(mErrors.begin());
1664 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001665 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666}
1667
1668GLenum Context::getResetStatus()
1669{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001670 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001671 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001672 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001673 // mResetStatus will be set by the markContextLost callback
1674 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001675 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001676 {
1677 mRenderer->notifyDeviceLost();
1678 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001679 }
1680
1681 GLenum status = mResetStatus;
1682
1683 if (mResetStatus != GL_NO_ERROR)
1684 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001685 ASSERT(mContextLost);
1686
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001687 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001688 {
1689 mResetStatus = GL_NO_ERROR;
1690 }
1691 }
Jamie Madill893ab082014-05-16 16:56:10 -04001692
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693 return status;
1694}
1695
1696bool Context::isResetNotificationEnabled()
1697{
1698 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1699}
1700
Corentin Walleze3b10e82015-05-20 11:06:25 -04001701const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001702{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001703 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001704}
1705
1706EGLenum Context::getClientType() const
1707{
1708 return mClientType;
1709}
1710
1711EGLenum Context::getRenderBuffer() const
1712{
Corentin Wallez37c39792015-08-20 14:19:46 -04001713 auto framebufferIt = mFramebufferMap.find(0);
1714 if (framebufferIt != mFramebufferMap.end())
1715 {
1716 const Framebuffer *framebuffer = framebufferIt->second;
1717 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1718
1719 ASSERT(backAttachment != nullptr);
1720 return backAttachment->getSurface()->getRenderBuffer();
1721 }
1722 else
1723 {
1724 return EGL_NONE;
1725 }
Régis Fénéon83107972015-02-05 12:57:44 +01001726}
1727
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001728VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001729{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001730 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001731 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1732 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001733 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001734 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1735 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001736 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001737
1738 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001739}
1740
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001741TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001742{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001743 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001744 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1745 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001746 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001747 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1748 transformFeedback->addRef();
1749 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001750 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001751
1752 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001753}
1754
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001755Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1756{
1757 // Can be called from Bind without a prior call to Gen.
1758 auto framebufferIt = mFramebufferMap.find(framebuffer);
1759 bool neverCreated = framebufferIt == mFramebufferMap.end();
1760 if (neverCreated || framebufferIt->second == nullptr)
1761 {
1762 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1763 if (neverCreated)
1764 {
1765 mFramebufferHandleAllocator.reserve(framebuffer);
1766 mFramebufferMap[framebuffer] = newFBO;
1767 return newFBO;
1768 }
1769
1770 framebufferIt->second = newFBO;
1771 }
1772
1773 return framebufferIt->second;
1774}
1775
Geoff Lang36167ab2015-12-07 10:27:14 -05001776bool Context::isVertexArrayGenerated(GLuint vertexArray)
1777{
1778 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1779}
1780
1781bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1782{
1783 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1784}
1785
Shannon Woods53a94a82014-06-24 15:20:36 -04001786void Context::detachTexture(GLuint texture)
1787{
1788 // Simple pass-through to State's detachTexture method, as textures do not require
1789 // allocation map management either here or in the resource manager at detach time.
1790 // Zero textures are held by the Context, and we don't attempt to request them from
1791 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001792 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001793}
1794
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795void Context::detachBuffer(GLuint buffer)
1796{
Yuly Novikov5807a532015-12-03 13:01:22 -05001797 // Simple pass-through to State's detachBuffer method, since
1798 // only buffer attachments to container objects that are bound to the current context
1799 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001800
Yuly Novikov5807a532015-12-03 13:01:22 -05001801 // [OpenGL ES 3.2] section 5.1.2 page 45:
1802 // Attachments to unbound container objects, such as
1803 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1804 // are not affected and continue to act as references on the deleted object
1805 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001806}
1807
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001808void Context::detachFramebuffer(GLuint framebuffer)
1809{
Shannon Woods53a94a82014-06-24 15:20:36 -04001810 // Framebuffer detachment is handled by Context, because 0 is a valid
1811 // Framebuffer object, and a pointer to it must be passed from Context
1812 // to State at binding time.
1813
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001814 // [OpenGL ES 2.0.24] section 4.4 page 107:
1815 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1816 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1817
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001818 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001819 {
1820 bindReadFramebuffer(0);
1821 }
1822
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001823 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001824 {
1825 bindDrawFramebuffer(0);
1826 }
1827}
1828
1829void Context::detachRenderbuffer(GLuint renderbuffer)
1830{
Shannon Woods53a94a82014-06-24 15:20:36 -04001831 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832}
1833
Jamie Madill57a89722013-07-02 11:57:03 -04001834void Context::detachVertexArray(GLuint vertexArray)
1835{
Jamie Madill77a72f62015-04-14 11:18:32 -04001836 // Vertex array detachment is handled by Context, because 0 is a valid
1837 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001838 // binding time.
1839
Jamie Madill57a89722013-07-02 11:57:03 -04001840 // [OpenGL ES 3.0.2] section 2.10 page 43:
1841 // If a vertex array object that is currently bound is deleted, the binding
1842 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001843 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001844 {
1845 bindVertexArray(0);
1846 }
1847}
1848
Geoff Langc8058452014-02-03 12:04:11 -05001849void Context::detachTransformFeedback(GLuint transformFeedback)
1850{
Shannon Woods53a94a82014-06-24 15:20:36 -04001851 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001852}
1853
Jamie Madilldc356042013-07-19 16:36:57 -04001854void Context::detachSampler(GLuint sampler)
1855{
Shannon Woods53a94a82014-06-24 15:20:36 -04001856 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001857}
1858
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001859void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1860{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001861 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001862}
1863
Jamie Madille29d1672013-07-19 16:36:57 -04001864void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1865{
1866 mResourceManager->checkSamplerAllocation(sampler);
1867
1868 Sampler *samplerObject = getSampler(sampler);
1869 ASSERT(samplerObject);
1870
Geoff Lang69cce582015-09-17 13:20:36 -04001871 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001872 switch (pname)
1873 {
Geoff Lang69cce582015-09-17 13:20:36 -04001874 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1875 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1876 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1877 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1878 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1879 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1880 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1881 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1882 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1883 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1884 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001885 }
Geoff Lang69cce582015-09-17 13:20:36 -04001886 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001887}
1888
1889void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1890{
1891 mResourceManager->checkSamplerAllocation(sampler);
1892
1893 Sampler *samplerObject = getSampler(sampler);
1894 ASSERT(samplerObject);
1895
Geoff Lang69cce582015-09-17 13:20:36 -04001896 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001897 switch (pname)
1898 {
Geoff Lang69cce582015-09-17 13:20:36 -04001899 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1900 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1901 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1902 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1903 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1904 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1905 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1906 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1907 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1908 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1909 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001910 }
Geoff Lang69cce582015-09-17 13:20:36 -04001911 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001912}
1913
Jamie Madill9675b802013-07-19 16:36:59 -04001914GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1915{
1916 mResourceManager->checkSamplerAllocation(sampler);
1917
1918 Sampler *samplerObject = getSampler(sampler);
1919 ASSERT(samplerObject);
1920
Geoff Lang69cce582015-09-17 13:20:36 -04001921 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001922 switch (pname)
1923 {
Geoff Lang69cce582015-09-17 13:20:36 -04001924 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1925 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1926 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1927 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1928 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1929 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001930 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1931 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001932 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1933 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1934 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001935 }
Geoff Lang69cce582015-09-17 13:20:36 -04001936 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001937}
1938
1939GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1940{
1941 mResourceManager->checkSamplerAllocation(sampler);
1942
1943 Sampler *samplerObject = getSampler(sampler);
1944 ASSERT(samplerObject);
1945
Geoff Lang69cce582015-09-17 13:20:36 -04001946 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001947 switch (pname)
1948 {
Geoff Lang69cce582015-09-17 13:20:36 -04001949 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1950 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1951 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1952 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1953 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1954 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1955 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1956 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1957 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1958 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1959 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001960 }
Geoff Lang69cce582015-09-17 13:20:36 -04001961 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001962}
1963
Olli Etuahof0fee072016-03-30 15:11:58 +03001964void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1965{
1966 gl::Program *programObject = getProgram(program);
1967 ASSERT(programObject != nullptr);
1968
1969 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1970 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1971}
1972
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001973void Context::initRendererString()
1974{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001975 std::ostringstream rendererString;
1976 rendererString << "ANGLE (";
1977 rendererString << mRenderer->getRendererDescription();
1978 rendererString << ")";
1979
Geoff Langcec35902014-04-16 10:52:36 -04001980 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001981}
1982
Geoff Langc0b9ef42014-07-02 10:02:37 -04001983const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001985 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001986}
1987
Geoff Langcec35902014-04-16 10:52:36 -04001988void Context::initExtensionStrings()
1989{
Geoff Lang493daf52014-07-03 13:38:44 -04001990 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001991
Geoff Langc0b9ef42014-07-02 10:02:37 -04001992 std::ostringstream combinedStringStream;
1993 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1994 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001995}
1996
Geoff Langc0b9ef42014-07-02 10:02:37 -04001997const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001998{
1999 return mExtensionString;
2000}
2001
Geoff Langc0b9ef42014-07-02 10:02:37 -04002002const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002003{
2004 return mExtensionStrings[idx];
2005}
2006
2007size_t Context::getExtensionStringCount() const
2008{
2009 return mExtensionStrings.size();
2010}
2011
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002012void Context::beginTransformFeedback(GLenum primitiveMode)
2013{
2014 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2015 ASSERT(transformFeedback != nullptr);
2016 ASSERT(!transformFeedback->isPaused());
2017
2018 transformFeedback->begin(primitiveMode, getState().getProgram());
2019}
2020
2021bool Context::hasActiveTransformFeedback(GLuint program) const
2022{
2023 for (auto pair : mTransformFeedbackMap)
2024 {
2025 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2026 {
2027 return true;
2028 }
2029 }
2030 return false;
2031}
2032
Geoff Lang493daf52014-07-03 13:38:44 -04002033void Context::initCaps(GLuint clientVersion)
2034{
2035 mCaps = mRenderer->getRendererCaps();
2036
2037 mExtensions = mRenderer->getRendererExtensions();
2038
Austin Kinross02df7962015-07-01 10:03:42 -07002039 mLimitations = mRenderer->getRendererLimitations();
2040
Geoff Lang493daf52014-07-03 13:38:44 -04002041 if (clientVersion < 3)
2042 {
2043 // Disable ES3+ extensions
2044 mExtensions.colorBufferFloat = false;
2045 }
2046
2047 if (clientVersion > 2)
2048 {
2049 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2050 //mExtensions.sRGB = false;
2051 }
2052
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 // Explicitly enable GL_KHR_debug
2054 mExtensions.debug = true;
2055 mExtensions.maxDebugMessageLength = 1024;
2056 mExtensions.maxDebugLoggedMessages = 1024;
2057 mExtensions.maxDebugGroupStackDepth = 1024;
2058 mExtensions.maxLabelLength = 1024;
2059
Geoff Lang301d1612014-07-09 10:34:37 -04002060 // Apply implementation limits
2061 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002062 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2063 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2064
2065 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002066
Geoff Lang900013c2014-07-07 11:32:19 -04002067 mCaps.compressedTextureFormats.clear();
2068
Geoff Lang493daf52014-07-03 13:38:44 -04002069 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2070 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2071 {
2072 GLenum format = i->first;
2073 TextureCaps formatCaps = i->second;
2074
Geoff Lang5d601382014-07-22 15:14:06 -04002075 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002076
Geoff Lang0d8b7242015-09-09 14:56:53 -04002077 // Update the format caps based on the client version and extensions.
2078 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2079 // ES3.
2080 formatCaps.texturable =
2081 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2082 formatCaps.renderable =
2083 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2084 formatCaps.filterable =
2085 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002086
2087 // OpenGL ES does not support multisampling with integer formats
2088 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002089 {
Geoff Langd87878e2014-09-19 15:42:59 -04002090 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002091 }
Geoff Langd87878e2014-09-19 15:42:59 -04002092
2093 if (formatCaps.texturable && formatInfo.compressed)
2094 {
2095 mCaps.compressedTextureFormats.push_back(format);
2096 }
2097
2098 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002099 }
2100}
2101
Jamie Madill1b94d432015-08-07 13:23:23 -04002102void Context::syncRendererState()
2103{
2104 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002105 mRenderer->syncState(mState, dirtyBits);
2106 mState.clearDirtyBits();
2107 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002108}
2109
Jamie Madillad9f24e2016-02-12 09:27:24 -05002110void Context::syncRendererState(const State::DirtyBits &bitMask,
2111 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002112{
2113 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002114 mRenderer->syncState(mState, dirtyBits);
2115 mState.clearDirtyBits(dirtyBits);
2116
Jamie Madillad9f24e2016-02-12 09:27:24 -05002117 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002118}
Jamie Madillc29968b2016-01-20 11:17:23 -05002119
2120void Context::blitFramebuffer(GLint srcX0,
2121 GLint srcY0,
2122 GLint srcX1,
2123 GLint srcY1,
2124 GLint dstX0,
2125 GLint dstY0,
2126 GLint dstX1,
2127 GLint dstY1,
2128 GLbitfield mask,
2129 GLenum filter)
2130{
2131 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2132 ASSERT(readFramebuffer);
2133
2134 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2135 ASSERT(drawFramebuffer);
2136
2137 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2138 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2139
Jamie Madillad9f24e2016-02-12 09:27:24 -05002140 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002141
2142 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2143 if (error.isError())
2144 {
2145 recordError(error);
2146 return;
2147 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148}
Jamie Madillc29968b2016-01-20 11:17:23 -05002149
2150void Context::clear(GLbitfield mask)
2151{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002152 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002153
2154 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2155 if (error.isError())
2156 {
2157 recordError(error);
2158 }
2159}
2160
2161void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2162{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002163 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002164
2165 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2166 if (error.isError())
2167 {
2168 recordError(error);
2169 }
2170}
2171
2172void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2173{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002174 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002175
2176 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2177 if (error.isError())
2178 {
2179 recordError(error);
2180 }
2181}
2182
2183void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2184{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002185 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002186
2187 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2188 if (error.isError())
2189 {
2190 recordError(error);
2191 }
2192}
2193
2194void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2195{
2196 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2197 ASSERT(framebufferObject);
2198
2199 // If a buffer is not present, the clear has no effect
2200 if (framebufferObject->getDepthbuffer() == nullptr &&
2201 framebufferObject->getStencilbuffer() == nullptr)
2202 {
2203 return;
2204 }
2205
Jamie Madillad9f24e2016-02-12 09:27:24 -05002206 syncStateForClear();
Jamie Madillc29968b2016-01-20 11:17:23 -05002207
2208 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2209 if (error.isError())
2210 {
2211 recordError(error);
2212 }
2213}
2214
2215void Context::readPixels(GLint x,
2216 GLint y,
2217 GLsizei width,
2218 GLsizei height,
2219 GLenum format,
2220 GLenum type,
2221 GLvoid *pixels)
2222{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002223 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002224
2225 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2226 ASSERT(framebufferObject);
2227
2228 Rectangle area(x, y, width, height);
2229 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2230 if (error.isError())
2231 {
2232 recordError(error);
2233 }
2234}
2235
2236void Context::copyTexImage2D(GLenum target,
2237 GLint level,
2238 GLenum internalformat,
2239 GLint x,
2240 GLint y,
2241 GLsizei width,
2242 GLsizei height,
2243 GLint border)
2244{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002245 // Only sync the read FBO
2246 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2247
Jamie Madillc29968b2016-01-20 11:17:23 -05002248 Rectangle sourceArea(x, y, width, height);
2249
2250 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2251 Texture *texture =
2252 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2253 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2254 if (error.isError())
2255 {
2256 recordError(error);
2257 }
2258}
2259
2260void Context::copyTexSubImage2D(GLenum target,
2261 GLint level,
2262 GLint xoffset,
2263 GLint yoffset,
2264 GLint x,
2265 GLint y,
2266 GLsizei width,
2267 GLsizei height)
2268{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002269 // Only sync the read FBO
2270 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2271
Jamie Madillc29968b2016-01-20 11:17:23 -05002272 Offset destOffset(xoffset, yoffset, 0);
2273 Rectangle sourceArea(x, y, width, height);
2274
2275 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2276 Texture *texture =
2277 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2278 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2279 if (error.isError())
2280 {
2281 recordError(error);
2282 }
2283}
2284
2285void Context::copyTexSubImage3D(GLenum target,
2286 GLint level,
2287 GLint xoffset,
2288 GLint yoffset,
2289 GLint zoffset,
2290 GLint x,
2291 GLint y,
2292 GLsizei width,
2293 GLsizei height)
2294{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002295 // Only sync the read FBO
2296 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2297
Jamie Madillc29968b2016-01-20 11:17:23 -05002298 Offset destOffset(xoffset, yoffset, zoffset);
2299 Rectangle sourceArea(x, y, width, height);
2300
2301 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2302 Texture *texture = getTargetTexture(target);
2303 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2304 if (error.isError())
2305 {
2306 recordError(error);
2307 }
2308}
2309
2310void Context::framebufferTexture2D(GLenum target,
2311 GLenum attachment,
2312 GLenum textarget,
2313 GLuint texture,
2314 GLint level)
2315{
2316 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2317 ASSERT(framebuffer);
2318
2319 if (texture != 0)
2320 {
2321 Texture *textureObj = getTexture(texture);
2322
2323 ImageIndex index = ImageIndex::MakeInvalid();
2324
2325 if (textarget == GL_TEXTURE_2D)
2326 {
2327 index = ImageIndex::Make2D(level);
2328 }
2329 else
2330 {
2331 ASSERT(IsCubeMapTextureTarget(textarget));
2332 index = ImageIndex::MakeCube(textarget, level);
2333 }
2334
2335 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2336 }
2337 else
2338 {
2339 framebuffer->resetAttachment(attachment);
2340 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002341
2342 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002343}
2344
2345void Context::framebufferRenderbuffer(GLenum target,
2346 GLenum attachment,
2347 GLenum renderbuffertarget,
2348 GLuint renderbuffer)
2349{
2350 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2351 ASSERT(framebuffer);
2352
2353 if (renderbuffer != 0)
2354 {
2355 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2356 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2357 renderbufferObject);
2358 }
2359 else
2360 {
2361 framebuffer->resetAttachment(attachment);
2362 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002363
2364 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002365}
2366
2367void Context::framebufferTextureLayer(GLenum target,
2368 GLenum attachment,
2369 GLuint texture,
2370 GLint level,
2371 GLint layer)
2372{
2373 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2374 ASSERT(framebuffer);
2375
2376 if (texture != 0)
2377 {
2378 Texture *textureObject = getTexture(texture);
2379
2380 ImageIndex index = ImageIndex::MakeInvalid();
2381
2382 if (textureObject->getTarget() == GL_TEXTURE_3D)
2383 {
2384 index = ImageIndex::Make3D(level, layer);
2385 }
2386 else
2387 {
2388 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2389 index = ImageIndex::Make2DArray(level, layer);
2390 }
2391
2392 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2393 }
2394 else
2395 {
2396 framebuffer->resetAttachment(attachment);
2397 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002398
2399 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002400}
2401
2402void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2403{
2404 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2405 ASSERT(framebuffer);
2406 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002407 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002408}
2409
2410void Context::readBuffer(GLenum mode)
2411{
2412 Framebuffer *readFBO = mState.getReadFramebuffer();
2413 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002414 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002415}
2416
2417void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2418{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002419 // Only sync the FBO
2420 mState.syncDirtyObject(target);
2421
Jamie Madillc29968b2016-01-20 11:17:23 -05002422 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2423 ASSERT(framebuffer);
2424
2425 // The specification isn't clear what should be done when the framebuffer isn't complete.
2426 // We leave it up to the framebuffer implementation to decide what to do.
2427 Error error = framebuffer->discard(numAttachments, attachments);
2428 if (error.isError())
2429 {
2430 recordError(error);
2431 }
2432}
2433
2434void Context::invalidateFramebuffer(GLenum target,
2435 GLsizei numAttachments,
2436 const GLenum *attachments)
2437{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002438 // Only sync the FBO
2439 mState.syncDirtyObject(target);
2440
Jamie Madillc29968b2016-01-20 11:17:23 -05002441 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2442 ASSERT(framebuffer);
2443
2444 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2445 {
2446 Error error = framebuffer->invalidate(numAttachments, attachments);
2447 if (error.isError())
2448 {
2449 recordError(error);
2450 return;
2451 }
2452 }
2453}
2454
2455void Context::invalidateSubFramebuffer(GLenum target,
2456 GLsizei numAttachments,
2457 const GLenum *attachments,
2458 GLint x,
2459 GLint y,
2460 GLsizei width,
2461 GLsizei height)
2462{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002463 // Only sync the FBO
2464 mState.syncDirtyObject(target);
2465
Jamie Madillc29968b2016-01-20 11:17:23 -05002466 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2467 ASSERT(framebuffer);
2468
2469 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2470 {
2471 Rectangle area(x, y, width, height);
2472 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2473 if (error.isError())
2474 {
2475 recordError(error);
2476 return;
2477 }
2478 }
2479}
2480
Jamie Madill73a84962016-02-12 09:27:23 -05002481void Context::texImage2D(GLenum target,
2482 GLint level,
2483 GLint internalformat,
2484 GLsizei width,
2485 GLsizei height,
2486 GLint border,
2487 GLenum format,
2488 GLenum type,
2489 const GLvoid *pixels)
2490{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002491 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002492
2493 Extents size(width, height, 1);
2494 Texture *texture =
2495 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2496 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2497 format, type, reinterpret_cast<const uint8_t *>(pixels));
2498 if (error.isError())
2499 {
2500 recordError(error);
2501 }
2502}
2503
2504void Context::texImage3D(GLenum target,
2505 GLint level,
2506 GLint internalformat,
2507 GLsizei width,
2508 GLsizei height,
2509 GLsizei depth,
2510 GLint border,
2511 GLenum format,
2512 GLenum type,
2513 const GLvoid *pixels)
2514{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002516
2517 Extents size(width, height, depth);
2518 Texture *texture = getTargetTexture(target);
2519 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2520 format, type, reinterpret_cast<const uint8_t *>(pixels));
2521 if (error.isError())
2522 {
2523 recordError(error);
2524 }
2525}
2526
2527void Context::texSubImage2D(GLenum target,
2528 GLint level,
2529 GLint xoffset,
2530 GLint yoffset,
2531 GLsizei width,
2532 GLsizei height,
2533 GLenum format,
2534 GLenum type,
2535 const GLvoid *pixels)
2536{
2537 // Zero sized uploads are valid but no-ops
2538 if (width == 0 || height == 0)
2539 {
2540 return;
2541 }
2542
Jamie Madillad9f24e2016-02-12 09:27:24 -05002543 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002544
2545 Box area(xoffset, yoffset, 0, width, height, 1);
2546 Texture *texture =
2547 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2548 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2549 reinterpret_cast<const uint8_t *>(pixels));
2550 if (error.isError())
2551 {
2552 recordError(error);
2553 }
2554}
2555
2556void Context::texSubImage3D(GLenum target,
2557 GLint level,
2558 GLint xoffset,
2559 GLint yoffset,
2560 GLint zoffset,
2561 GLsizei width,
2562 GLsizei height,
2563 GLsizei depth,
2564 GLenum format,
2565 GLenum type,
2566 const GLvoid *pixels)
2567{
2568 // Zero sized uploads are valid but no-ops
2569 if (width == 0 || height == 0 || depth == 0)
2570 {
2571 return;
2572 }
2573
Jamie Madillad9f24e2016-02-12 09:27:24 -05002574 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002575
2576 Box area(xoffset, yoffset, zoffset, width, height, depth);
2577 Texture *texture = getTargetTexture(target);
2578 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2579 reinterpret_cast<const uint8_t *>(pixels));
2580 if (error.isError())
2581 {
2582 recordError(error);
2583 }
2584}
2585
2586void Context::compressedTexImage2D(GLenum target,
2587 GLint level,
2588 GLenum internalformat,
2589 GLsizei width,
2590 GLsizei height,
2591 GLint border,
2592 GLsizei imageSize,
2593 const GLvoid *data)
2594{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002595 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002596
2597 Extents size(width, height, 1);
2598 Texture *texture =
2599 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2600 Error error =
2601 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2602 imageSize, reinterpret_cast<const uint8_t *>(data));
2603 if (error.isError())
2604 {
2605 recordError(error);
2606 }
2607}
2608
2609void Context::compressedTexImage3D(GLenum target,
2610 GLint level,
2611 GLenum internalformat,
2612 GLsizei width,
2613 GLsizei height,
2614 GLsizei depth,
2615 GLint border,
2616 GLsizei imageSize,
2617 const GLvoid *data)
2618{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002619 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002620
2621 Extents size(width, height, depth);
2622 Texture *texture = getTargetTexture(target);
2623 Error error =
2624 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2625 imageSize, reinterpret_cast<const uint8_t *>(data));
2626 if (error.isError())
2627 {
2628 recordError(error);
2629 }
2630}
2631
2632void Context::compressedTexSubImage2D(GLenum target,
2633 GLint level,
2634 GLint xoffset,
2635 GLint yoffset,
2636 GLsizei width,
2637 GLsizei height,
2638 GLenum format,
2639 GLsizei imageSize,
2640 const GLvoid *data)
2641{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002642 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002643
2644 Box area(xoffset, yoffset, 0, width, height, 1);
2645 Texture *texture =
2646 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2647 Error error =
2648 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2649 imageSize, reinterpret_cast<const uint8_t *>(data));
2650 if (error.isError())
2651 {
2652 recordError(error);
2653 }
2654}
2655
2656void Context::compressedTexSubImage3D(GLenum target,
2657 GLint level,
2658 GLint xoffset,
2659 GLint yoffset,
2660 GLint zoffset,
2661 GLsizei width,
2662 GLsizei height,
2663 GLsizei depth,
2664 GLenum format,
2665 GLsizei imageSize,
2666 const GLvoid *data)
2667{
2668 // Zero sized uploads are valid but no-ops
2669 if (width == 0 || height == 0)
2670 {
2671 return;
2672 }
2673
Jamie Madillad9f24e2016-02-12 09:27:24 -05002674 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002675
2676 Box area(xoffset, yoffset, zoffset, width, height, depth);
2677 Texture *texture = getTargetTexture(target);
2678 Error error =
2679 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2680 imageSize, reinterpret_cast<const uint8_t *>(data));
2681 if (error.isError())
2682 {
2683 recordError(error);
2684 }
2685}
2686
Olli Etuaho4f667482016-03-30 15:56:35 +03002687void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2688{
2689 Buffer *buffer = getState().getTargetBuffer(target);
2690 ASSERT(buffer);
2691
2692 if (!buffer->isMapped())
2693 {
2694 *params = nullptr;
2695 }
2696 else
2697 {
2698 *params = buffer->getMapPointer();
2699 }
2700}
2701
2702GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2703{
2704 Buffer *buffer = getState().getTargetBuffer(target);
2705 ASSERT(buffer);
2706
2707 Error error = buffer->map(access);
2708 if (error.isError())
2709 {
2710 recordError(error);
2711 return nullptr;
2712 }
2713
2714 return buffer->getMapPointer();
2715}
2716
2717GLboolean Context::unmapBuffer(GLenum target)
2718{
2719 Buffer *buffer = getState().getTargetBuffer(target);
2720 ASSERT(buffer);
2721
2722 GLboolean result;
2723 Error error = buffer->unmap(&result);
2724 if (error.isError())
2725 {
2726 recordError(error);
2727 return GL_FALSE;
2728 }
2729
2730 return result;
2731}
2732
2733GLvoid *Context::mapBufferRange(GLenum target,
2734 GLintptr offset,
2735 GLsizeiptr length,
2736 GLbitfield access)
2737{
2738 Buffer *buffer = getState().getTargetBuffer(target);
2739 ASSERT(buffer);
2740
2741 Error error = buffer->mapRange(offset, length, access);
2742 if (error.isError())
2743 {
2744 recordError(error);
2745 return nullptr;
2746 }
2747
2748 return buffer->getMapPointer();
2749}
2750
2751void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2752{
2753 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2754}
2755
Jamie Madillad9f24e2016-02-12 09:27:24 -05002756void Context::syncStateForReadPixels()
2757{
2758 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2759}
2760
2761void Context::syncStateForTexImage()
2762{
2763 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2764}
2765
2766void Context::syncStateForClear()
2767{
2768 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2769}
2770
2771void Context::syncStateForBlit()
2772{
2773 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2774}
2775
Jamie Madillc29968b2016-01-20 11:17:23 -05002776} // namespace gl