blob: ca43a10907a4e006ac5f146a7c8be5285a84c809 [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"
Jamie Madill437fa652016-05-03 15:13:24 -040034#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040035#include "libANGLE/renderer/EGLImplFactory.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000036
Geoff Langf6db0982015-08-25 13:04:00 -040037namespace
38{
39
Ian Ewell3ffd78b2016-01-22 16:09:42 -050040template <typename T>
41gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
42{
43 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
44 ASSERT(queryObject != nullptr);
45
46 switch (pname)
47 {
48 case GL_QUERY_RESULT_EXT:
49 return queryObject->getResult(params);
50 case GL_QUERY_RESULT_AVAILABLE_EXT:
51 {
52 bool available;
53 gl::Error error = queryObject->isResultAvailable(&available);
54 if (!error.isError())
55 {
56 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
57 }
58 return error;
59 }
60 default:
61 UNREACHABLE();
62 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
63 }
64}
65
Geoff Langf6db0982015-08-25 13:04:00 -040066void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
67{
Geoff Lang1a683462015-09-29 15:09:59 -040068 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040069 {
70 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
71 tfBufferIndex++)
72 {
73 const OffsetBindingPointer<gl::Buffer> &buffer =
74 transformFeedback->getIndexedBuffer(tfBufferIndex);
75 if (buffer.get() != nullptr)
76 {
77 buffer->onTransformFeedback();
78 }
79 }
80 }
81}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050082
83// Attribute map queries.
84EGLint GetClientVersion(const egl::AttributeMap &attribs)
85{
Ian Ewellec2c0c52016-04-05 13:46:26 -040086 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -050087}
88
89GLenum GetResetStrategy(const egl::AttributeMap &attribs)
90{
Ian Ewellec2c0c52016-04-05 13:46:26 -040091 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
92 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -050093 switch (attrib)
94 {
95 case EGL_NO_RESET_NOTIFICATION:
96 return GL_NO_RESET_NOTIFICATION_EXT;
97 case EGL_LOSE_CONTEXT_ON_RESET:
98 return GL_LOSE_CONTEXT_ON_RESET_EXT;
99 default:
100 UNREACHABLE();
101 return GL_NONE;
102 }
103}
104
105bool GetRobustAccess(const egl::AttributeMap &attribs)
106{
107 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
108}
109
110bool GetDebug(const egl::AttributeMap &attribs)
111{
112 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
113}
114
115bool GetNoError(const egl::AttributeMap &attribs)
116{
117 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
118}
119
Geoff Langf6db0982015-08-25 13:04:00 -0400120} // anonymous namespace
121
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000122namespace gl
123{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000124
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400125Context::Context(rx::EGLImplFactory *implFactory,
126 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400127 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500128 const egl::AttributeMap &attribs)
129 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500130 mState,
131 mCaps,
132 mTextureCaps,
133 mExtensions,
134 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500135 mLimitations,
136 GetNoError(attribs)),
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400137 mImplementation(implFactory->createContext(getData())),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mCompiler(nullptr),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400140 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141 mClientType(EGL_OPENGL_ES_API),
142 mHasBeenCurrent(false),
143 mContextLost(false),
144 mResetStatus(GL_NO_ERROR),
145 mResetStrategy(GetResetStrategy(attribs)),
146 mRobustAccess(GetRobustAccess(attribs)),
147 mCurrentSurface(nullptr),
148 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000149{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500150 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000151
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500152 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400153
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500154 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100155
Shannon Woods53a94a82014-06-24 15:20:36 -0400156 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400157
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400158 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000159 {
160 mResourceManager = shareContext->mResourceManager;
161 mResourceManager->addRef();
162 }
163 else
164 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400165 mResourceManager = new ResourceManager(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000166 }
167
Jamie Madillc185cb82015-04-28 12:39:08 -0400168 mData.resourceManager = mResourceManager;
169
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000170 // [OpenGL ES 2.0.24] section 3.7 page 83:
171 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
172 // and cube map texture state vectors respectively associated with them.
173 // In order that access to these initial textures not be lost, they are treated as texture
174 // objects all of whose names are 0.
175
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400176 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500177 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500178
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400179 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500180 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400181
182 if (mClientVersion >= 3)
183 {
184 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400185 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500186 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400187
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400188 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500189 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400190 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000191
Ian Ewellbda75592016-04-18 17:25:54 -0400192 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
193 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400194 Texture *zeroTextureExternal =
195 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400196 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
197 }
198
Jamie Madille6382c32014-11-07 15:05:26 -0500199 mState.initializeZeroTextures(mZeroTextures);
200
Jamie Madill57a89722013-07-02 11:57:03 -0400201 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000202 bindArrayBuffer(0);
203 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400204
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205 bindRenderbuffer(0);
206
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000207 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400208 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000209 {
210 bindIndexedUniformBuffer(0, i, 0, -1);
211 }
212
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000213 bindCopyReadBuffer(0);
214 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000215 bindPixelPackBuffer(0);
216 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000217
Geoff Lang1a683462015-09-29 15:09:59 -0400218 if (mClientVersion >= 3)
219 {
220 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
221 // In the initial state, a default transform feedback object is bound and treated as
222 // a transform feedback object with a name of zero. That object is bound any time
223 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400224 bindTransformFeedback(0);
225 }
Geoff Langc8058452014-02-03 12:04:11 -0500226
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400227 mCompiler = new Compiler(mImplementation.get(), getData());
Jamie Madillad9f24e2016-02-12 09:27:24 -0500228
229 // Initialize dirty bit masks
230 // TODO(jmadill): additional ES3 state
231 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
232 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
233 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
234 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
235 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
236 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400237 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500238 // No dirty objects.
239
240 // Readpixels uses the pack state and read FBO
241 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
242 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
243 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
244 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
245 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400246 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500247 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
248
249 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
250 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
251 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
252 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
253 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
254 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
255 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
256 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
257 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
258 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
259 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
260 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
261
262 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
263 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
264 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
265 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400266
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400267 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268}
269
270Context::~Context()
271{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500272 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000273
Corentin Wallez37c39792015-08-20 14:19:46 -0400274 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400276 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400277 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400278 {
279 SafeDelete(framebuffer.second);
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281 }
282
Corentin Wallez80b24112015-08-25 16:41:57 -0400283 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400285 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286 }
287
Corentin Wallez80b24112015-08-25 16:41:57 -0400288 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400290 if (query.second != nullptr)
291 {
292 query.second->release();
293 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294 }
295
Corentin Wallez80b24112015-08-25 16:41:57 -0400296 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400297 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400298 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400299 }
300
Corentin Wallez80b24112015-08-25 16:41:57 -0400301 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500302 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500303 if (transformFeedback.second != nullptr)
304 {
305 transformFeedback.second->release();
306 }
Geoff Langc8058452014-02-03 12:04:11 -0500307 }
308
Jamie Madilldedd7b92014-11-05 16:30:36 -0500309 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
313 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314
Corentin Wallez51706ea2015-08-07 14:39:22 -0400315 if (mCurrentSurface != nullptr)
316 {
317 releaseSurface();
318 }
319
Jamie Madill1e9ae072014-11-06 15:27:21 -0500320 if (mResourceManager)
321 {
322 mResourceManager->release();
323 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500324
325 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326}
327
daniel@transgaming.comad629872012-11-28 19:32:06 +0000328void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329{
Jamie Madill77a72f62015-04-14 11:18:32 -0400330 ASSERT(surface != nullptr);
331
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332 if (!mHasBeenCurrent)
333 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400335 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Shannon Woods53a94a82014-06-24 15:20:36 -0400337 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
338 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000339
340 mHasBeenCurrent = true;
341 }
342
Jamie Madill1b94d432015-08-07 13:23:23 -0400343 // TODO(jmadill): Rework this when we support ContextImpl
344 mState.setAllDirtyBits();
345
Corentin Wallez51706ea2015-08-07 14:39:22 -0400346 if (mCurrentSurface)
347 {
348 releaseSurface();
349 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000350 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400351 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000352
Corentin Wallez37c39792015-08-20 14:19:46 -0400353 // Update default framebuffer, the binding of the previous default
354 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400355 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400356 Framebuffer *newDefault = surface->getDefaultFramebuffer();
357 if (mState.getReadFramebuffer() == nullptr)
358 {
359 mState.setReadFramebufferBinding(newDefault);
360 }
361 if (mState.getDrawFramebuffer() == nullptr)
362 {
363 mState.setDrawFramebufferBinding(newDefault);
364 }
365 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400366 }
Ian Ewell292f0052016-02-04 10:37:32 -0500367
368 // Notify the renderer of a context switch
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400369 mImplementation->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370}
371
Jamie Madill77a72f62015-04-14 11:18:32 -0400372void Context::releaseSurface()
373{
Corentin Wallez37c39792015-08-20 14:19:46 -0400374 ASSERT(mCurrentSurface != nullptr);
375
376 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400377 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400378 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
379 if (mState.getReadFramebuffer() == currentDefault)
380 {
381 mState.setReadFramebufferBinding(nullptr);
382 }
383 if (mState.getDrawFramebuffer() == currentDefault)
384 {
385 mState.setDrawFramebufferBinding(nullptr);
386 }
387 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400388 }
389
Corentin Wallez51706ea2015-08-07 14:39:22 -0400390 mCurrentSurface->setIsCurrent(false);
391 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400392}
393
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000394// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395void Context::markContextLost()
396{
397 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
398 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
399 mContextLost = true;
400}
401
402bool Context::isContextLost()
403{
404 return mContextLost;
405}
406
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407GLuint Context::createBuffer()
408{
409 return mResourceManager->createBuffer();
410}
411
412GLuint Context::createProgram()
413{
414 return mResourceManager->createProgram();
415}
416
417GLuint Context::createShader(GLenum type)
418{
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400419 return mResourceManager->createShader(mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
422GLuint Context::createTexture()
423{
424 return mResourceManager->createTexture();
425}
426
427GLuint Context::createRenderbuffer()
428{
429 return mResourceManager->createRenderbuffer();
430}
431
Geoff Lang882033e2014-09-30 11:26:07 -0400432GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400433{
434 GLuint handle = mResourceManager->createFenceSync();
435
Cooper Partind8e62a32015-01-29 15:21:25 -0800436 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400437}
438
Jamie Madill57a89722013-07-02 11:57:03 -0400439GLuint Context::createVertexArray()
440{
Geoff Lang36167ab2015-12-07 10:27:14 -0500441 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
442 mVertexArrayMap[vertexArray] = nullptr;
443 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400444}
445
Jamie Madilldc356042013-07-19 16:36:57 -0400446GLuint Context::createSampler()
447{
448 return mResourceManager->createSampler();
449}
450
Geoff Langc8058452014-02-03 12:04:11 -0500451GLuint Context::createTransformFeedback()
452{
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
454 mTransformFeedbackMap[transformFeedback] = nullptr;
455 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500456}
457
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458// Returns an unused framebuffer name
459GLuint Context::createFramebuffer()
460{
461 GLuint handle = mFramebufferHandleAllocator.allocate();
462
463 mFramebufferMap[handle] = NULL;
464
465 return handle;
466}
467
Jamie Madill33dc8432013-07-26 11:55:05 -0400468GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469{
Jamie Madill33dc8432013-07-26 11:55:05 -0400470 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400472 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473
474 return handle;
475}
476
477// Returns an unused query name
478GLuint Context::createQuery()
479{
480 GLuint handle = mQueryHandleAllocator.allocate();
481
482 mQueryMap[handle] = NULL;
483
484 return handle;
485}
486
487void Context::deleteBuffer(GLuint buffer)
488{
489 if (mResourceManager->getBuffer(buffer))
490 {
491 detachBuffer(buffer);
492 }
Jamie Madill893ab082014-05-16 16:56:10 -0400493
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494 mResourceManager->deleteBuffer(buffer);
495}
496
497void Context::deleteShader(GLuint shader)
498{
499 mResourceManager->deleteShader(shader);
500}
501
502void Context::deleteProgram(GLuint program)
503{
504 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000505}
506
507void Context::deleteTexture(GLuint texture)
508{
509 if (mResourceManager->getTexture(texture))
510 {
511 detachTexture(texture);
512 }
513
514 mResourceManager->deleteTexture(texture);
515}
516
517void Context::deleteRenderbuffer(GLuint renderbuffer)
518{
519 if (mResourceManager->getRenderbuffer(renderbuffer))
520 {
521 detachRenderbuffer(renderbuffer);
522 }
Jamie Madill893ab082014-05-16 16:56:10 -0400523
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524 mResourceManager->deleteRenderbuffer(renderbuffer);
525}
526
Jamie Madillcd055f82013-07-26 11:55:15 -0400527void Context::deleteFenceSync(GLsync fenceSync)
528{
529 // The spec specifies the underlying Fence object is not deleted until all current
530 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
531 // and since our API is currently designed for being called from a single thread, we can delete
532 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700533 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400534}
535
Jamie Madill57a89722013-07-02 11:57:03 -0400536void Context::deleteVertexArray(GLuint vertexArray)
537{
Geoff Lang36167ab2015-12-07 10:27:14 -0500538 auto iter = mVertexArrayMap.find(vertexArray);
539 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000540 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500541 VertexArray *vertexArrayObject = iter->second;
542 if (vertexArrayObject != nullptr)
543 {
544 detachVertexArray(vertexArray);
545 delete vertexArrayObject;
546 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000547
Geoff Lang36167ab2015-12-07 10:27:14 -0500548 mVertexArrayMap.erase(iter);
549 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400550 }
551}
552
Jamie Madilldc356042013-07-19 16:36:57 -0400553void Context::deleteSampler(GLuint sampler)
554{
555 if (mResourceManager->getSampler(sampler))
556 {
557 detachSampler(sampler);
558 }
559
560 mResourceManager->deleteSampler(sampler);
561}
562
Geoff Langc8058452014-02-03 12:04:11 -0500563void Context::deleteTransformFeedback(GLuint transformFeedback)
564{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500565 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500566 if (iter != mTransformFeedbackMap.end())
567 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 TransformFeedback *transformFeedbackObject = iter->second;
569 if (transformFeedbackObject != nullptr)
570 {
571 detachTransformFeedback(transformFeedback);
572 transformFeedbackObject->release();
573 }
574
Geoff Lang50b3fe82015-12-08 14:49:12 +0000575 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500576 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500577 }
578}
579
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580void Context::deleteFramebuffer(GLuint framebuffer)
581{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500582 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583
584 if (framebufferObject != mFramebufferMap.end())
585 {
586 detachFramebuffer(framebuffer);
587
588 mFramebufferHandleAllocator.release(framebufferObject->first);
589 delete framebufferObject->second;
590 mFramebufferMap.erase(framebufferObject);
591 }
592}
593
Jamie Madill33dc8432013-07-26 11:55:05 -0400594void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500596 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597
Jamie Madill33dc8432013-07-26 11:55:05 -0400598 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400600 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000601 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400602 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603 }
604}
605
606void Context::deleteQuery(GLuint query)
607{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500608 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609 if (queryObject != mQueryMap.end())
610 {
611 mQueryHandleAllocator.release(queryObject->first);
612 if (queryObject->second)
613 {
614 queryObject->second->release();
615 }
616 mQueryMap.erase(queryObject);
617 }
618}
619
Geoff Lang70d0f492015-12-10 17:45:46 -0500620Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621{
622 return mResourceManager->getBuffer(handle);
623}
624
Geoff Lang48dcae72014-02-05 16:28:24 -0500625Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626{
627 return mResourceManager->getShader(handle);
628}
629
Geoff Lang48dcae72014-02-05 16:28:24 -0500630Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631{
632 return mResourceManager->getProgram(handle);
633}
634
Jamie Madill570f7c82014-07-03 10:38:54 -0400635Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636{
637 return mResourceManager->getTexture(handle);
638}
639
Geoff Lang70d0f492015-12-10 17:45:46 -0500640Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641{
642 return mResourceManager->getRenderbuffer(handle);
643}
644
Jamie Madillcd055f82013-07-26 11:55:15 -0400645FenceSync *Context::getFenceSync(GLsync handle) const
646{
Minmin Gong794e0002015-04-07 18:31:54 -0700647 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400648}
649
Jamie Madill57a89722013-07-02 11:57:03 -0400650VertexArray *Context::getVertexArray(GLuint handle) const
651{
652 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500653 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400654}
655
Jamie Madilldc356042013-07-19 16:36:57 -0400656Sampler *Context::getSampler(GLuint handle) const
657{
658 return mResourceManager->getSampler(handle);
659}
660
Geoff Langc8058452014-02-03 12:04:11 -0500661TransformFeedback *Context::getTransformFeedback(GLuint handle) const
662{
Geoff Lang36167ab2015-12-07 10:27:14 -0500663 auto iter = mTransformFeedbackMap.find(handle);
664 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500665}
666
Geoff Lang70d0f492015-12-10 17:45:46 -0500667LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
668{
669 switch (identifier)
670 {
671 case GL_BUFFER:
672 return getBuffer(name);
673 case GL_SHADER:
674 return getShader(name);
675 case GL_PROGRAM:
676 return getProgram(name);
677 case GL_VERTEX_ARRAY:
678 return getVertexArray(name);
679 case GL_QUERY:
680 return getQuery(name);
681 case GL_TRANSFORM_FEEDBACK:
682 return getTransformFeedback(name);
683 case GL_SAMPLER:
684 return getSampler(name);
685 case GL_TEXTURE:
686 return getTexture(name);
687 case GL_RENDERBUFFER:
688 return getRenderbuffer(name);
689 case GL_FRAMEBUFFER:
690 return getFramebuffer(name);
691 default:
692 UNREACHABLE();
693 return nullptr;
694 }
695}
696
697LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
698{
699 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
700}
701
Jamie Madilldc356042013-07-19 16:36:57 -0400702bool Context::isSampler(GLuint samplerName) const
703{
704 return mResourceManager->isSampler(samplerName);
705}
706
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500707void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
710 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000711}
712
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500713void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500715 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
716 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000717}
718
Jamie Madilldedd7b92014-11-05 16:30:36 -0500719void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000720{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500721 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000722
Jamie Madilldedd7b92014-11-05 16:30:36 -0500723 if (handle == 0)
724 {
725 texture = mZeroTextures[target].get();
726 }
727 else
728 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500729 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500730 }
731
732 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500733 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000734}
735
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500736void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000737{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500738 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
739 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740}
741
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500742void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000743{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500744 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
745 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000746}
747
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500748void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000749{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500750 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
751 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000752}
753
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500754void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400755{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500756 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
757 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400758}
759
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500760void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400761{
Geoff Lang76b10c92014-09-05 16:28:14 -0400762 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500763 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
764 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400765}
766
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500767void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000768{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500769 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
770 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000771}
772
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500773void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
774 GLuint index,
775 GLintptr offset,
776 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000777{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500778 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
779 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000780}
781
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500782void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000783{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500784 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
785 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000786}
787
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500788void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
789 GLuint index,
790 GLintptr offset,
791 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000792{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500793 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
794 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000795}
796
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000798{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
800 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000801}
802
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000804{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500805 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
806 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000807}
808
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500809void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000810{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500811 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
812 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000813}
814
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500815void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000816{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500817 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
818 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000819}
820
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821void Context::useProgram(GLuint program)
822{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500823 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000824}
825
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500826void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500827{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500828 TransformFeedback *transformFeedback =
829 checkTransformFeedbackAllocation(transformFeedbackHandle);
830 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500831}
832
Geoff Lang5aad9672014-09-08 11:10:42 -0400833Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400836 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837
Geoff Lang5aad9672014-09-08 11:10:42 -0400838 // begin query
839 Error error = queryObject->begin();
840 if (error.isError())
841 {
842 return error;
843 }
844
845 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400846 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847
Geoff Lang5aad9672014-09-08 11:10:42 -0400848 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849}
850
Geoff Lang5aad9672014-09-08 11:10:42 -0400851Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852{
Shannon Woods53a94a82014-06-24 15:20:36 -0400853 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400854 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855
Geoff Lang5aad9672014-09-08 11:10:42 -0400856 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857
Geoff Lang5aad9672014-09-08 11:10:42 -0400858 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400859 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400860
861 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862}
863
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500864Error Context::queryCounter(GLuint id, GLenum target)
865{
866 ASSERT(target == GL_TIMESTAMP_EXT);
867
868 Query *queryObject = getQuery(id, true, target);
869 ASSERT(queryObject);
870
871 return queryObject->queryCounter();
872}
873
874void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
875{
876 switch (pname)
877 {
878 case GL_CURRENT_QUERY_EXT:
879 params[0] = getState().getActiveQueryId(target);
880 break;
881 case GL_QUERY_COUNTER_BITS_EXT:
882 switch (target)
883 {
884 case GL_TIME_ELAPSED_EXT:
885 params[0] = getExtensions().queryCounterBitsTimeElapsed;
886 break;
887 case GL_TIMESTAMP_EXT:
888 params[0] = getExtensions().queryCounterBitsTimestamp;
889 break;
890 default:
891 UNREACHABLE();
892 params[0] = 0;
893 break;
894 }
895 break;
896 default:
897 UNREACHABLE();
898 return;
899 }
900}
901
902Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
903{
904 return GetQueryObjectParameter(this, id, pname, params);
905}
906
907Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
908{
909 return GetQueryObjectParameter(this, id, pname, params);
910}
911
912Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
913{
914 return GetQueryObjectParameter(this, id, pname, params);
915}
916
917Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
918{
919 return GetQueryObjectParameter(this, id, pname, params);
920}
921
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500922Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500924 auto framebufferIt = mFramebufferMap.find(handle);
925 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madill33dc8432013-07-26 11:55:05 -0400928FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500930 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madill33dc8432013-07-26 11:55:05 -0400932 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933 {
934 return NULL;
935 }
936 else
937 {
938 return fence->second;
939 }
940}
941
942Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
943{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500944 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945
946 if (query == mQueryMap.end())
947 {
948 return NULL;
949 }
950 else
951 {
952 if (!query->second && create)
953 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400954 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955 query->second->addRef();
956 }
957 return query->second;
958 }
959}
960
Geoff Lang70d0f492015-12-10 17:45:46 -0500961Query *Context::getQuery(GLuint handle) const
962{
963 auto iter = mQueryMap.find(handle);
964 return (iter != mQueryMap.end()) ? iter->second : nullptr;
965}
966
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500967Texture *Context::getTargetTexture(GLenum target) const
968{
Ian Ewellbda75592016-04-18 17:25:54 -0400969 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500970 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000971}
972
Geoff Lang76b10c92014-09-05 16:28:14 -0400973Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976}
977
Geoff Lang492a7e42014-11-05 13:27:06 -0500978Compiler *Context::getCompiler() const
979{
980 return mCompiler;
981}
982
Jamie Madill893ab082014-05-16 16:56:10 -0400983void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
985 switch (pname)
986 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000987 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000988 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400990 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400991 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill893ab082014-05-16 16:56:10 -0400995void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996{
Shannon Woods53a94a82014-06-24 15:20:36 -0400997 // Queries about context capabilities and maximums are answered by Context.
998 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999 switch (pname)
1000 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 params[0] = mCaps.minAliasedLineWidth;
1003 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 break;
1005 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001006 params[0] = mCaps.minAliasedPointSize;
1007 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001009 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001010 ASSERT(mExtensions.textureFilterAnisotropic);
1011 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001012 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001013 case GL_MAX_TEXTURE_LOD_BIAS:
1014 *params = mCaps.maxLODBias;
1015 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001017 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001018 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020}
1021
Jamie Madill893ab082014-05-16 16:56:10 -04001022void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023{
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 // Queries about context capabilities and maximums are answered by Context.
1025 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001026
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001027 switch (pname)
1028 {
Geoff Lang301d1612014-07-09 10:34:37 -04001029 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1030 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1031 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001032 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1033 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1034 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001035 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1036 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1037 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001038 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001039 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1040 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1041 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001042 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001043 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001044 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1045 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1046 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1047 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001048 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1049 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001050 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1051 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001052 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001053 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1054 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1055 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1056 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001057 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1058 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001059 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1060 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001061 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1062 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1063 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001064 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1065 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1066 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001067 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 case GL_MAX_VIEWPORT_DIMS:
1069 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001070 params[0] = mCaps.maxViewportWidth;
1071 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072 }
1073 break;
1074 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001075 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1078 *params = mResetStrategy;
1079 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001080 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001081 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001083 case GL_SHADER_BINARY_FORMATS:
1084 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1085 break;
1086 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001087 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001088 break;
1089 case GL_PROGRAM_BINARY_FORMATS:
1090 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001092 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001093 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001094 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001095
1096 // GL_KHR_debug
1097 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1098 *params = mExtensions.maxDebugMessageLength;
1099 break;
1100 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1101 *params = mExtensions.maxDebugLoggedMessages;
1102 break;
1103 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1104 *params = mExtensions.maxDebugGroupStackDepth;
1105 break;
1106 case GL_MAX_LABEL_LENGTH:
1107 *params = mExtensions.maxLabelLength;
1108 break;
1109
Ian Ewell53f59f42016-01-28 17:36:55 -05001110 // GL_EXT_disjoint_timer_query
1111 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001112 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001113 break;
1114
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001116 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001117 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001118 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001119}
1120
Jamie Madill893ab082014-05-16 16:56:10 -04001121void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001122{
Shannon Woods53a94a82014-06-24 15:20:36 -04001123 // Queries about context capabilities and maximums are answered by Context.
1124 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001125 switch (pname)
1126 {
1127 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001128 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001129 break;
1130 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001131 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001132 break;
1133 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001134 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 break;
1136 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001137 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001138 break;
1139 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001140 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001141 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001142
1143 // GL_EXT_disjoint_timer_query
1144 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001145 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001146 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001147 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001148 UNREACHABLE();
1149 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001150 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001151}
1152
Geoff Lang70d0f492015-12-10 17:45:46 -05001153void Context::getPointerv(GLenum pname, void **params) const
1154{
1155 mState.getPointerv(pname, params);
1156}
1157
Shannon Woods1b2fb852013-08-19 14:28:48 -04001158bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1159{
Shannon Woods53a94a82014-06-24 15:20:36 -04001160 // Queries about context capabilities and maximums are answered by Context.
1161 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001162 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 // mere passthrough.
1164 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001165}
1166
1167bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1168{
Shannon Woods53a94a82014-06-24 15:20:36 -04001169 // Queries about context capabilities and maximums are answered by Context.
1170 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001171 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001172 // mere passthrough.
1173 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001174}
1175
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1177{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001178 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1179 {
1180 *type = GL_INT;
1181 *numParams = 1;
1182 return true;
1183 }
1184
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1186 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1187 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001188 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1190 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1191 // application.
1192 switch (pname)
1193 {
1194 case GL_COMPRESSED_TEXTURE_FORMATS:
1195 {
1196 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001197 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001198 }
1199 return true;
1200 case GL_PROGRAM_BINARY_FORMATS_OES:
1201 {
1202 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001203 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001205 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 case GL_SHADER_BINARY_FORMATS:
1207 {
1208 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001209 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001211 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213 case GL_MAX_VERTEX_ATTRIBS:
1214 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1215 case GL_MAX_VARYING_VECTORS:
1216 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1217 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1218 case GL_MAX_TEXTURE_IMAGE_UNITS:
1219 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1220 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001221 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001222 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 case GL_NUM_SHADER_BINARY_FORMATS:
1224 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1225 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001226 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1227 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1228 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 case GL_RENDERBUFFER_BINDING:
1230 case GL_CURRENT_PROGRAM:
1231 case GL_PACK_ALIGNMENT:
1232 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1233 case GL_UNPACK_ALIGNMENT:
1234 case GL_GENERATE_MIPMAP_HINT:
1235 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1236 case GL_RED_BITS:
1237 case GL_GREEN_BITS:
1238 case GL_BLUE_BITS:
1239 case GL_ALPHA_BITS:
1240 case GL_DEPTH_BITS:
1241 case GL_STENCIL_BITS:
1242 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1243 case GL_CULL_FACE_MODE:
1244 case GL_FRONT_FACE:
1245 case GL_ACTIVE_TEXTURE:
1246 case GL_STENCIL_FUNC:
1247 case GL_STENCIL_VALUE_MASK:
1248 case GL_STENCIL_REF:
1249 case GL_STENCIL_FAIL:
1250 case GL_STENCIL_PASS_DEPTH_FAIL:
1251 case GL_STENCIL_PASS_DEPTH_PASS:
1252 case GL_STENCIL_BACK_FUNC:
1253 case GL_STENCIL_BACK_VALUE_MASK:
1254 case GL_STENCIL_BACK_REF:
1255 case GL_STENCIL_BACK_FAIL:
1256 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1257 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1258 case GL_DEPTH_FUNC:
1259 case GL_BLEND_SRC_RGB:
1260 case GL_BLEND_SRC_ALPHA:
1261 case GL_BLEND_DST_RGB:
1262 case GL_BLEND_DST_ALPHA:
1263 case GL_BLEND_EQUATION_RGB:
1264 case GL_BLEND_EQUATION_ALPHA:
1265 case GL_STENCIL_WRITEMASK:
1266 case GL_STENCIL_BACK_WRITEMASK:
1267 case GL_STENCIL_CLEAR_VALUE:
1268 case GL_SUBPIXEL_BITS:
1269 case GL_MAX_TEXTURE_SIZE:
1270 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1271 case GL_SAMPLE_BUFFERS:
1272 case GL_SAMPLES:
1273 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1274 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1275 case GL_TEXTURE_BINDING_2D:
1276 case GL_TEXTURE_BINDING_CUBE_MAP:
1277 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1278 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 {
1280 *type = GL_INT;
1281 *numParams = 1;
1282 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001283 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 case GL_MAX_SAMPLES_ANGLE:
1285 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001286 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287 {
1288 *type = GL_INT;
1289 *numParams = 1;
1290 }
1291 else
1292 {
1293 return false;
1294 }
1295 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001296 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297 case GL_MAX_VIEWPORT_DIMS:
1298 {
1299 *type = GL_INT;
1300 *numParams = 2;
1301 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001302 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001303 case GL_VIEWPORT:
1304 case GL_SCISSOR_BOX:
1305 {
1306 *type = GL_INT;
1307 *numParams = 4;
1308 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001309 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310 case GL_SHADER_COMPILER:
1311 case GL_SAMPLE_COVERAGE_INVERT:
1312 case GL_DEPTH_WRITEMASK:
1313 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1314 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1315 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1316 case GL_SAMPLE_COVERAGE:
1317 case GL_SCISSOR_TEST:
1318 case GL_STENCIL_TEST:
1319 case GL_DEPTH_TEST:
1320 case GL_BLEND:
1321 case GL_DITHER:
1322 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1323 {
1324 *type = GL_BOOL;
1325 *numParams = 1;
1326 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001327 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_COLOR_WRITEMASK:
1329 {
1330 *type = GL_BOOL;
1331 *numParams = 4;
1332 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001333 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 case GL_POLYGON_OFFSET_FACTOR:
1335 case GL_POLYGON_OFFSET_UNITS:
1336 case GL_SAMPLE_COVERAGE_VALUE:
1337 case GL_DEPTH_CLEAR_VALUE:
1338 case GL_LINE_WIDTH:
1339 {
1340 *type = GL_FLOAT;
1341 *numParams = 1;
1342 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001343 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001344 case GL_ALIASED_LINE_WIDTH_RANGE:
1345 case GL_ALIASED_POINT_SIZE_RANGE:
1346 case GL_DEPTH_RANGE:
1347 {
1348 *type = GL_FLOAT;
1349 *numParams = 2;
1350 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001351 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352 case GL_COLOR_CLEAR_VALUE:
1353 case GL_BLEND_COLOR:
1354 {
1355 *type = GL_FLOAT;
1356 *numParams = 4;
1357 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001358 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001359 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001360 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001361 {
1362 return false;
1363 }
1364 *type = GL_FLOAT;
1365 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001366 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001367 case GL_TIMESTAMP_EXT:
1368 if (!mExtensions.disjointTimerQuery)
1369 {
1370 return false;
1371 }
1372 *type = GL_INT_64_ANGLEX;
1373 *numParams = 1;
1374 return true;
1375 case GL_GPU_DISJOINT_EXT:
1376 if (!mExtensions.disjointTimerQuery)
1377 {
1378 return false;
1379 }
1380 *type = GL_INT;
1381 *numParams = 1;
1382 return true;
Sami Väisänena797e062016-05-12 15:23:40 +03001383 case GL_COVERAGE_MODULATION_CHROMIUM:
1384 if (!mExtensions.framebufferMixedSamples)
1385 {
1386 return false;
1387 }
1388 *type = GL_INT;
1389 *numParams = 1;
1390 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001391 }
1392
Geoff Lang70d0f492015-12-10 17:45:46 -05001393 if (mExtensions.debug)
1394 {
1395 switch (pname)
1396 {
1397 case GL_DEBUG_LOGGED_MESSAGES:
1398 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1399 case GL_DEBUG_GROUP_STACK_DEPTH:
1400 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1401 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1402 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1403 case GL_MAX_LABEL_LENGTH:
1404 *type = GL_INT;
1405 *numParams = 1;
1406 return true;
1407
1408 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1409 case GL_DEBUG_OUTPUT:
1410 *type = GL_BOOL;
1411 *numParams = 1;
1412 return true;
1413 }
1414 }
1415
Sami Väisänen74c23472016-05-09 17:30:30 +03001416 if (mExtensions.multisampleCompatibility)
1417 {
1418 switch (pname)
1419 {
1420 case GL_MULTISAMPLE_EXT:
1421 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1422 *type = GL_BOOL;
1423 *numParams = 1;
1424 return true;
1425 }
1426 }
1427
Austin Kinrossbc781f32015-10-26 09:27:38 -07001428 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1429 switch (pname)
1430 {
1431 case GL_PACK_ROW_LENGTH:
1432 case GL_PACK_SKIP_ROWS:
1433 case GL_PACK_SKIP_PIXELS:
1434 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1435 {
1436 return false;
1437 }
1438 *type = GL_INT;
1439 *numParams = 1;
1440 return true;
1441 case GL_UNPACK_ROW_LENGTH:
1442 case GL_UNPACK_SKIP_ROWS:
1443 case GL_UNPACK_SKIP_PIXELS:
1444 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1445 {
1446 return false;
1447 }
1448 *type = GL_INT;
1449 *numParams = 1;
1450 return true;
1451 case GL_VERTEX_ARRAY_BINDING:
1452 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1453 {
1454 return false;
1455 }
1456 *type = GL_INT;
1457 *numParams = 1;
1458 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001459 case GL_PIXEL_PACK_BUFFER_BINDING:
1460 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1461 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1462 {
1463 return false;
1464 }
1465 *type = GL_INT;
1466 *numParams = 1;
1467 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001468 }
1469
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001470 if (mClientVersion < 3)
1471 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001472 return false;
1473 }
1474
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001475 // Check for ES3.0+ parameter names
1476 switch (pname)
1477 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001478 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1479 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001480 case GL_UNIFORM_BUFFER_BINDING:
1481 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001482 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001483 case GL_COPY_READ_BUFFER_BINDING:
1484 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001485 case GL_SAMPLER_BINDING:
1486 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001487 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001488 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001489 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001490 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001491 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1492 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1493 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001494 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1495 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001496 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001497 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1498 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001499 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1500 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001501 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001502 case GL_MAJOR_VERSION:
1503 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001504 case GL_MAX_ELEMENTS_INDICES:
1505 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001506 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001507 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001508 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001509 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001510 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001511 {
1512 *type = GL_INT;
1513 *numParams = 1;
1514 }
1515 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516
1517 case GL_MAX_ELEMENT_INDEX:
1518 case GL_MAX_UNIFORM_BLOCK_SIZE:
1519 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1520 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1521 case GL_MAX_SERVER_WAIT_TIMEOUT:
1522 {
1523 *type = GL_INT_64_ANGLEX;
1524 *numParams = 1;
1525 }
1526 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001527
1528 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001529 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001530 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001531 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001532 {
1533 *type = GL_BOOL;
1534 *numParams = 1;
1535 }
1536 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001537
1538 case GL_MAX_TEXTURE_LOD_BIAS:
1539 {
1540 *type = GL_FLOAT;
1541 *numParams = 1;
1542 }
1543 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001544 }
1545
1546 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001547}
1548
Shannon Woods1b2fb852013-08-19 14:28:48 -04001549bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1550{
1551 if (mClientVersion < 3)
1552 {
1553 return false;
1554 }
1555
1556 switch (target)
1557 {
1558 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1559 case GL_UNIFORM_BUFFER_BINDING:
1560 {
1561 *type = GL_INT;
1562 *numParams = 1;
1563 }
1564 return true;
1565 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1566 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1567 case GL_UNIFORM_BUFFER_START:
1568 case GL_UNIFORM_BUFFER_SIZE:
1569 {
1570 *type = GL_INT_64_ANGLEX;
1571 *numParams = 1;
1572 }
1573 }
1574
1575 return false;
1576}
1577
Geoff Langf6db0982015-08-25 13:04:00 -04001578Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001579{
Jamie Madill1b94d432015-08-07 13:23:23 -04001580 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001581 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Geoff Langf6db0982015-08-25 13:04:00 -04001582 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001583
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001584 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001585}
1586
Geoff Langf6db0982015-08-25 13:04:00 -04001587Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1588{
1589 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001590 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Geoff Langf6db0982015-08-25 13:04:00 -04001591 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1592
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001593 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001594}
1595
1596Error Context::drawElements(GLenum mode,
1597 GLsizei count,
1598 GLenum type,
1599 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001600 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001601{
Jamie Madill1b94d432015-08-07 13:23:23 -04001602 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001603 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001604}
1605
1606Error Context::drawElementsInstanced(GLenum mode,
1607 GLsizei count,
1608 GLenum type,
1609 const GLvoid *indices,
1610 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001611 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001612{
1613 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001614 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1615 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001616}
1617
1618Error Context::drawRangeElements(GLenum mode,
1619 GLuint start,
1620 GLuint end,
1621 GLsizei count,
1622 GLenum type,
1623 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001624 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001625{
1626 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628}
1629
Geoff Lang129753a2015-01-09 16:52:09 -05001630Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001631{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001632 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001633}
1634
1635Error Context::finish()
1636{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001637 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001638}
1639
Austin Kinross6ee1e782015-05-29 17:05:37 -07001640void Context::insertEventMarker(GLsizei length, const char *marker)
1641{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001642 ASSERT(mImplementation);
1643 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001644}
1645
1646void Context::pushGroupMarker(GLsizei length, const char *marker)
1647{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001648 ASSERT(mImplementation);
1649 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001650}
1651
1652void Context::popGroupMarker()
1653{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001654 ASSERT(mImplementation);
1655 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001656}
1657
Geoff Langd8605522016-04-13 10:19:12 -04001658void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1659{
1660 Program *programObject = getProgram(program);
1661 ASSERT(programObject);
1662
1663 programObject->bindUniformLocation(location, name);
1664}
1665
Sami Väisänena797e062016-05-12 15:23:40 +03001666void Context::setCoverageModulation(GLenum components)
1667{
1668 mState.setCoverageModulation(components);
1669}
1670
1671
Jamie Madill437fa652016-05-03 15:13:24 -04001672void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001673{
Geoff Langda5777c2014-07-11 09:52:58 -04001674 if (error.isError())
1675 {
1676 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001677
1678 if (!error.getMessage().empty())
1679 {
1680 auto &debug = mState.getDebug();
1681 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1682 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1683 }
Geoff Langda5777c2014-07-11 09:52:58 -04001684 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001685}
1686
1687// Get one of the recorded errors and clear its flag, if any.
1688// [OpenGL ES 2.0.24] section 2.5 page 13.
1689GLenum Context::getError()
1690{
Geoff Langda5777c2014-07-11 09:52:58 -04001691 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001692 {
Geoff Langda5777c2014-07-11 09:52:58 -04001693 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001694 }
Geoff Langda5777c2014-07-11 09:52:58 -04001695 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001696 {
Geoff Langda5777c2014-07-11 09:52:58 -04001697 GLenum error = *mErrors.begin();
1698 mErrors.erase(mErrors.begin());
1699 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001700 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001701}
1702
1703GLenum Context::getResetStatus()
1704{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001705 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001706 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001707 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001708 // mResetStatus will be set by the markContextLost callback
1709 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001710 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001711 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001712 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001713 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001714 }
1715
1716 GLenum status = mResetStatus;
1717
1718 if (mResetStatus != GL_NO_ERROR)
1719 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001720 ASSERT(mContextLost);
1721
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001722 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001723 {
1724 mResetStatus = GL_NO_ERROR;
1725 }
1726 }
Jamie Madill893ab082014-05-16 16:56:10 -04001727
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001728 return status;
1729}
1730
1731bool Context::isResetNotificationEnabled()
1732{
1733 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1734}
1735
Corentin Walleze3b10e82015-05-20 11:06:25 -04001736const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001737{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001738 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001739}
1740
1741EGLenum Context::getClientType() const
1742{
1743 return mClientType;
1744}
1745
1746EGLenum Context::getRenderBuffer() const
1747{
Corentin Wallez37c39792015-08-20 14:19:46 -04001748 auto framebufferIt = mFramebufferMap.find(0);
1749 if (framebufferIt != mFramebufferMap.end())
1750 {
1751 const Framebuffer *framebuffer = framebufferIt->second;
1752 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1753
1754 ASSERT(backAttachment != nullptr);
1755 return backAttachment->getSurface()->getRenderBuffer();
1756 }
1757 else
1758 {
1759 return EGL_NONE;
1760 }
Régis Fénéon83107972015-02-05 12:57:44 +01001761}
1762
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001763VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001764{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001765 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001766 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1767 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001768 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001769 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1770
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001771 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001772 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001773
1774 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001775}
1776
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001777TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001778{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001779 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001780 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1781 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001782 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001783 transformFeedback =
1784 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001785 transformFeedback->addRef();
1786 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001787 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001788
1789 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001790}
1791
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001792Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1793{
1794 // Can be called from Bind without a prior call to Gen.
1795 auto framebufferIt = mFramebufferMap.find(framebuffer);
1796 bool neverCreated = framebufferIt == mFramebufferMap.end();
1797 if (neverCreated || framebufferIt->second == nullptr)
1798 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001799 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001800 if (neverCreated)
1801 {
1802 mFramebufferHandleAllocator.reserve(framebuffer);
1803 mFramebufferMap[framebuffer] = newFBO;
1804 return newFBO;
1805 }
1806
1807 framebufferIt->second = newFBO;
1808 }
1809
1810 return framebufferIt->second;
1811}
1812
Geoff Lang36167ab2015-12-07 10:27:14 -05001813bool Context::isVertexArrayGenerated(GLuint vertexArray)
1814{
1815 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1816}
1817
1818bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1819{
1820 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1821}
1822
Shannon Woods53a94a82014-06-24 15:20:36 -04001823void Context::detachTexture(GLuint texture)
1824{
1825 // Simple pass-through to State's detachTexture method, as textures do not require
1826 // allocation map management either here or in the resource manager at detach time.
1827 // Zero textures are held by the Context, and we don't attempt to request them from
1828 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001829 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001830}
1831
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832void Context::detachBuffer(GLuint buffer)
1833{
Yuly Novikov5807a532015-12-03 13:01:22 -05001834 // Simple pass-through to State's detachBuffer method, since
1835 // only buffer attachments to container objects that are bound to the current context
1836 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001837
Yuly Novikov5807a532015-12-03 13:01:22 -05001838 // [OpenGL ES 3.2] section 5.1.2 page 45:
1839 // Attachments to unbound container objects, such as
1840 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1841 // are not affected and continue to act as references on the deleted object
1842 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001843}
1844
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001845void Context::detachFramebuffer(GLuint framebuffer)
1846{
Shannon Woods53a94a82014-06-24 15:20:36 -04001847 // Framebuffer detachment is handled by Context, because 0 is a valid
1848 // Framebuffer object, and a pointer to it must be passed from Context
1849 // to State at binding time.
1850
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001851 // [OpenGL ES 2.0.24] section 4.4 page 107:
1852 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1853 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1854
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001855 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001856 {
1857 bindReadFramebuffer(0);
1858 }
1859
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001860 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001861 {
1862 bindDrawFramebuffer(0);
1863 }
1864}
1865
1866void Context::detachRenderbuffer(GLuint renderbuffer)
1867{
Shannon Woods53a94a82014-06-24 15:20:36 -04001868 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001869}
1870
Jamie Madill57a89722013-07-02 11:57:03 -04001871void Context::detachVertexArray(GLuint vertexArray)
1872{
Jamie Madill77a72f62015-04-14 11:18:32 -04001873 // Vertex array detachment is handled by Context, because 0 is a valid
1874 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001875 // binding time.
1876
Jamie Madill57a89722013-07-02 11:57:03 -04001877 // [OpenGL ES 3.0.2] section 2.10 page 43:
1878 // If a vertex array object that is currently bound is deleted, the binding
1879 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001880 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001881 {
1882 bindVertexArray(0);
1883 }
1884}
1885
Geoff Langc8058452014-02-03 12:04:11 -05001886void Context::detachTransformFeedback(GLuint transformFeedback)
1887{
Corentin Walleza2257da2016-04-19 16:43:12 -04001888 // Transform feedback detachment is handled by Context, because 0 is a valid
1889 // transform feedback, and a pointer to it must be passed from Context to State at
1890 // binding time.
1891
1892 // The OpenGL specification doesn't mention what should happen when the currently bound
1893 // transform feedback object is deleted. Since it is a container object, we treat it like
1894 // VAOs and FBOs and set the current bound transform feedback back to 0.
1895 if (mState.removeTransformFeedbackBinding(transformFeedback))
1896 {
1897 bindTransformFeedback(0);
1898 }
Geoff Langc8058452014-02-03 12:04:11 -05001899}
1900
Jamie Madilldc356042013-07-19 16:36:57 -04001901void Context::detachSampler(GLuint sampler)
1902{
Shannon Woods53a94a82014-06-24 15:20:36 -04001903 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001904}
1905
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001906void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1907{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001908 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001909}
1910
Jamie Madille29d1672013-07-19 16:36:57 -04001911void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1912{
1913 mResourceManager->checkSamplerAllocation(sampler);
1914
1915 Sampler *samplerObject = getSampler(sampler);
1916 ASSERT(samplerObject);
1917
Geoff Lang69cce582015-09-17 13:20:36 -04001918 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001919 switch (pname)
1920 {
Geoff Lang69cce582015-09-17 13:20:36 -04001921 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1922 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1923 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1924 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1925 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1926 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1927 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1928 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1929 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1930 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1931 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001932 }
Geoff Lang69cce582015-09-17 13:20:36 -04001933 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001934}
1935
1936void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1937{
1938 mResourceManager->checkSamplerAllocation(sampler);
1939
1940 Sampler *samplerObject = getSampler(sampler);
1941 ASSERT(samplerObject);
1942
Geoff Lang69cce582015-09-17 13:20:36 -04001943 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001944 switch (pname)
1945 {
Geoff Lang69cce582015-09-17 13:20:36 -04001946 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1947 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1948 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1949 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1950 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1951 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1952 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1953 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1954 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1955 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1956 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001957 }
Geoff Lang69cce582015-09-17 13:20:36 -04001958 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001959}
1960
Jamie Madill9675b802013-07-19 16:36:59 -04001961GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1962{
1963 mResourceManager->checkSamplerAllocation(sampler);
1964
1965 Sampler *samplerObject = getSampler(sampler);
1966 ASSERT(samplerObject);
1967
Geoff Lang69cce582015-09-17 13:20:36 -04001968 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001969 switch (pname)
1970 {
Geoff Lang69cce582015-09-17 13:20:36 -04001971 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1972 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1973 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1974 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1975 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1976 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001977 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1978 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001979 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1980 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1981 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001982 }
Geoff Lang69cce582015-09-17 13:20:36 -04001983 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001984}
1985
1986GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1987{
1988 mResourceManager->checkSamplerAllocation(sampler);
1989
1990 Sampler *samplerObject = getSampler(sampler);
1991 ASSERT(samplerObject);
1992
Geoff Lang69cce582015-09-17 13:20:36 -04001993 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001994 switch (pname)
1995 {
Geoff Lang69cce582015-09-17 13:20:36 -04001996 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1997 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1998 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1999 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2000 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2001 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2002 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2003 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2004 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2005 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2006 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002007 }
Geoff Lang69cce582015-09-17 13:20:36 -04002008 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002009}
2010
Olli Etuahof0fee072016-03-30 15:11:58 +03002011void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2012{
2013 gl::Program *programObject = getProgram(program);
2014 ASSERT(programObject != nullptr);
2015
2016 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2017 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2018}
2019
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002020void Context::initRendererString()
2021{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002022 std::ostringstream rendererString;
2023 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002024 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002025 rendererString << ")";
2026
Geoff Langcec35902014-04-16 10:52:36 -04002027 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002028}
2029
Geoff Langc0b9ef42014-07-02 10:02:37 -04002030const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002031{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002032 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002033}
2034
Geoff Langcec35902014-04-16 10:52:36 -04002035void Context::initExtensionStrings()
2036{
Geoff Lang493daf52014-07-03 13:38:44 -04002037 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002038
Geoff Langc0b9ef42014-07-02 10:02:37 -04002039 std::ostringstream combinedStringStream;
2040 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2041 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002042}
2043
Geoff Langc0b9ef42014-07-02 10:02:37 -04002044const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002045{
2046 return mExtensionString;
2047}
2048
Geoff Langc0b9ef42014-07-02 10:02:37 -04002049const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002050{
2051 return mExtensionStrings[idx];
2052}
2053
2054size_t Context::getExtensionStringCount() const
2055{
2056 return mExtensionStrings.size();
2057}
2058
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002059void Context::beginTransformFeedback(GLenum primitiveMode)
2060{
2061 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2062 ASSERT(transformFeedback != nullptr);
2063 ASSERT(!transformFeedback->isPaused());
2064
2065 transformFeedback->begin(primitiveMode, getState().getProgram());
2066}
2067
2068bool Context::hasActiveTransformFeedback(GLuint program) const
2069{
2070 for (auto pair : mTransformFeedbackMap)
2071 {
2072 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2073 {
2074 return true;
2075 }
2076 }
2077 return false;
2078}
2079
Geoff Lang493daf52014-07-03 13:38:44 -04002080void Context::initCaps(GLuint clientVersion)
2081{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002082 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002083
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002084 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002085
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002086 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002087
Geoff Lang493daf52014-07-03 13:38:44 -04002088 if (clientVersion < 3)
2089 {
2090 // Disable ES3+ extensions
2091 mExtensions.colorBufferFloat = false;
2092 }
2093
2094 if (clientVersion > 2)
2095 {
2096 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2097 //mExtensions.sRGB = false;
2098 }
2099
Geoff Lang70d0f492015-12-10 17:45:46 -05002100 // Explicitly enable GL_KHR_debug
2101 mExtensions.debug = true;
2102 mExtensions.maxDebugMessageLength = 1024;
2103 mExtensions.maxDebugLoggedMessages = 1024;
2104 mExtensions.maxDebugGroupStackDepth = 1024;
2105 mExtensions.maxLabelLength = 1024;
2106
Geoff Lang301d1612014-07-09 10:34:37 -04002107 // Apply implementation limits
2108 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002109 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2110 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2111
2112 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002113
Geoff Lang900013c2014-07-07 11:32:19 -04002114 mCaps.compressedTextureFormats.clear();
2115
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002116 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002117 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2118 {
2119 GLenum format = i->first;
2120 TextureCaps formatCaps = i->second;
2121
Geoff Lang5d601382014-07-22 15:14:06 -04002122 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002123
Geoff Lang0d8b7242015-09-09 14:56:53 -04002124 // Update the format caps based on the client version and extensions.
2125 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2126 // ES3.
2127 formatCaps.texturable =
2128 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2129 formatCaps.renderable =
2130 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2131 formatCaps.filterable =
2132 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002133
2134 // OpenGL ES does not support multisampling with integer formats
2135 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002136 {
Geoff Langd87878e2014-09-19 15:42:59 -04002137 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002138 }
Geoff Langd87878e2014-09-19 15:42:59 -04002139
2140 if (formatCaps.texturable && formatInfo.compressed)
2141 {
2142 mCaps.compressedTextureFormats.push_back(format);
2143 }
2144
2145 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002146 }
2147}
2148
Jamie Madill1b94d432015-08-07 13:23:23 -04002149void Context::syncRendererState()
2150{
2151 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002152 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002153 mState.clearDirtyBits();
2154 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002155}
2156
Jamie Madillad9f24e2016-02-12 09:27:24 -05002157void Context::syncRendererState(const State::DirtyBits &bitMask,
2158 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002159{
2160 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002161 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002162 mState.clearDirtyBits(dirtyBits);
2163
Jamie Madillad9f24e2016-02-12 09:27:24 -05002164 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002165}
Jamie Madillc29968b2016-01-20 11:17:23 -05002166
2167void Context::blitFramebuffer(GLint srcX0,
2168 GLint srcY0,
2169 GLint srcX1,
2170 GLint srcY1,
2171 GLint dstX0,
2172 GLint dstY0,
2173 GLint dstX1,
2174 GLint dstY1,
2175 GLbitfield mask,
2176 GLenum filter)
2177{
Jamie Madillc29968b2016-01-20 11:17:23 -05002178 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2179 ASSERT(drawFramebuffer);
2180
2181 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2182 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2183
Jamie Madillad9f24e2016-02-12 09:27:24 -05002184 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002185
Jamie Madill8415b5f2016-04-26 13:41:39 -04002186 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002187}
Jamie Madillc29968b2016-01-20 11:17:23 -05002188
2189void Context::clear(GLbitfield mask)
2190{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002191 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002192 handleError(mState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002193}
2194
2195void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2196{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002197 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002198 handleError(mState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2199 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002200}
2201
2202void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2203{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002204 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002205 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2206 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002207}
2208
2209void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2210{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002211 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002212 handleError(mState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2213 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002214}
2215
2216void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2217{
2218 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2219 ASSERT(framebufferObject);
2220
2221 // If a buffer is not present, the clear has no effect
2222 if (framebufferObject->getDepthbuffer() == nullptr &&
2223 framebufferObject->getStencilbuffer() == nullptr)
2224 {
2225 return;
2226 }
2227
Jamie Madillad9f24e2016-02-12 09:27:24 -05002228 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002229 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2230 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002231}
2232
2233void Context::readPixels(GLint x,
2234 GLint y,
2235 GLsizei width,
2236 GLsizei height,
2237 GLenum format,
2238 GLenum type,
2239 GLvoid *pixels)
2240{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002241 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002242
2243 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2244 ASSERT(framebufferObject);
2245
2246 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002247 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002248}
2249
2250void Context::copyTexImage2D(GLenum target,
2251 GLint level,
2252 GLenum internalformat,
2253 GLint x,
2254 GLint y,
2255 GLsizei width,
2256 GLsizei height,
2257 GLint border)
2258{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002259 // Only sync the read FBO
2260 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2261
Jamie Madillc29968b2016-01-20 11:17:23 -05002262 Rectangle sourceArea(x, y, width, height);
2263
2264 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2265 Texture *texture =
2266 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002267 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002268}
2269
2270void Context::copyTexSubImage2D(GLenum target,
2271 GLint level,
2272 GLint xoffset,
2273 GLint yoffset,
2274 GLint x,
2275 GLint y,
2276 GLsizei width,
2277 GLsizei height)
2278{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002279 // Only sync the read FBO
2280 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2281
Jamie Madillc29968b2016-01-20 11:17:23 -05002282 Offset destOffset(xoffset, yoffset, 0);
2283 Rectangle sourceArea(x, y, width, height);
2284
2285 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2286 Texture *texture =
2287 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002288 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002289}
2290
2291void Context::copyTexSubImage3D(GLenum target,
2292 GLint level,
2293 GLint xoffset,
2294 GLint yoffset,
2295 GLint zoffset,
2296 GLint x,
2297 GLint y,
2298 GLsizei width,
2299 GLsizei height)
2300{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002301 // Only sync the read FBO
2302 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2303
Jamie Madillc29968b2016-01-20 11:17:23 -05002304 Offset destOffset(xoffset, yoffset, zoffset);
2305 Rectangle sourceArea(x, y, width, height);
2306
2307 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2308 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002309 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002310}
2311
2312void Context::framebufferTexture2D(GLenum target,
2313 GLenum attachment,
2314 GLenum textarget,
2315 GLuint texture,
2316 GLint level)
2317{
2318 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2319 ASSERT(framebuffer);
2320
2321 if (texture != 0)
2322 {
2323 Texture *textureObj = getTexture(texture);
2324
2325 ImageIndex index = ImageIndex::MakeInvalid();
2326
2327 if (textarget == GL_TEXTURE_2D)
2328 {
2329 index = ImageIndex::Make2D(level);
2330 }
2331 else
2332 {
2333 ASSERT(IsCubeMapTextureTarget(textarget));
2334 index = ImageIndex::MakeCube(textarget, level);
2335 }
2336
2337 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2338 }
2339 else
2340 {
2341 framebuffer->resetAttachment(attachment);
2342 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002343
2344 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002345}
2346
2347void Context::framebufferRenderbuffer(GLenum target,
2348 GLenum attachment,
2349 GLenum renderbuffertarget,
2350 GLuint renderbuffer)
2351{
2352 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2353 ASSERT(framebuffer);
2354
2355 if (renderbuffer != 0)
2356 {
2357 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2358 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2359 renderbufferObject);
2360 }
2361 else
2362 {
2363 framebuffer->resetAttachment(attachment);
2364 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002365
2366 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002367}
2368
2369void Context::framebufferTextureLayer(GLenum target,
2370 GLenum attachment,
2371 GLuint texture,
2372 GLint level,
2373 GLint layer)
2374{
2375 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2376 ASSERT(framebuffer);
2377
2378 if (texture != 0)
2379 {
2380 Texture *textureObject = getTexture(texture);
2381
2382 ImageIndex index = ImageIndex::MakeInvalid();
2383
2384 if (textureObject->getTarget() == GL_TEXTURE_3D)
2385 {
2386 index = ImageIndex::Make3D(level, layer);
2387 }
2388 else
2389 {
2390 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2391 index = ImageIndex::Make2DArray(level, layer);
2392 }
2393
2394 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2395 }
2396 else
2397 {
2398 framebuffer->resetAttachment(attachment);
2399 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002400
2401 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002402}
2403
2404void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2405{
2406 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2407 ASSERT(framebuffer);
2408 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002409 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002410}
2411
2412void Context::readBuffer(GLenum mode)
2413{
2414 Framebuffer *readFBO = mState.getReadFramebuffer();
2415 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002416 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002417}
2418
2419void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2420{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002421 // Only sync the FBO
2422 mState.syncDirtyObject(target);
2423
Jamie Madillc29968b2016-01-20 11:17:23 -05002424 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2425 ASSERT(framebuffer);
2426
2427 // The specification isn't clear what should be done when the framebuffer isn't complete.
2428 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002429 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002430}
2431
2432void Context::invalidateFramebuffer(GLenum target,
2433 GLsizei numAttachments,
2434 const GLenum *attachments)
2435{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002436 // Only sync the FBO
2437 mState.syncDirtyObject(target);
2438
Jamie Madillc29968b2016-01-20 11:17:23 -05002439 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2440 ASSERT(framebuffer);
2441
Jamie Madill437fa652016-05-03 15:13:24 -04002442 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002443 {
Jamie Madill437fa652016-05-03 15:13:24 -04002444 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002445 }
Jamie Madill437fa652016-05-03 15:13:24 -04002446
2447 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002448}
2449
2450void Context::invalidateSubFramebuffer(GLenum target,
2451 GLsizei numAttachments,
2452 const GLenum *attachments,
2453 GLint x,
2454 GLint y,
2455 GLsizei width,
2456 GLsizei height)
2457{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002458 // Only sync the FBO
2459 mState.syncDirtyObject(target);
2460
Jamie Madillc29968b2016-01-20 11:17:23 -05002461 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2462 ASSERT(framebuffer);
2463
Jamie Madill437fa652016-05-03 15:13:24 -04002464 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002465 {
Jamie Madill437fa652016-05-03 15:13:24 -04002466 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002467 }
Jamie Madill437fa652016-05-03 15:13:24 -04002468
2469 Rectangle area(x, y, width, height);
2470 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002471}
2472
Jamie Madill73a84962016-02-12 09:27:23 -05002473void Context::texImage2D(GLenum target,
2474 GLint level,
2475 GLint internalformat,
2476 GLsizei width,
2477 GLsizei height,
2478 GLint border,
2479 GLenum format,
2480 GLenum type,
2481 const GLvoid *pixels)
2482{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002483 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002484
2485 Extents size(width, height, 1);
2486 Texture *texture =
2487 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002488 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2489 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002490}
2491
2492void Context::texImage3D(GLenum target,
2493 GLint level,
2494 GLint internalformat,
2495 GLsizei width,
2496 GLsizei height,
2497 GLsizei depth,
2498 GLint border,
2499 GLenum format,
2500 GLenum type,
2501 const GLvoid *pixels)
2502{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002503 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002504
2505 Extents size(width, height, depth);
2506 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002507 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2508 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002509}
2510
2511void Context::texSubImage2D(GLenum target,
2512 GLint level,
2513 GLint xoffset,
2514 GLint yoffset,
2515 GLsizei width,
2516 GLsizei height,
2517 GLenum format,
2518 GLenum type,
2519 const GLvoid *pixels)
2520{
2521 // Zero sized uploads are valid but no-ops
2522 if (width == 0 || height == 0)
2523 {
2524 return;
2525 }
2526
Jamie Madillad9f24e2016-02-12 09:27:24 -05002527 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002528
2529 Box area(xoffset, yoffset, 0, width, height, 1);
2530 Texture *texture =
2531 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002532 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2533 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002534}
2535
2536void Context::texSubImage3D(GLenum target,
2537 GLint level,
2538 GLint xoffset,
2539 GLint yoffset,
2540 GLint zoffset,
2541 GLsizei width,
2542 GLsizei height,
2543 GLsizei depth,
2544 GLenum format,
2545 GLenum type,
2546 const GLvoid *pixels)
2547{
2548 // Zero sized uploads are valid but no-ops
2549 if (width == 0 || height == 0 || depth == 0)
2550 {
2551 return;
2552 }
2553
Jamie Madillad9f24e2016-02-12 09:27:24 -05002554 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002555
2556 Box area(xoffset, yoffset, zoffset, width, height, depth);
2557 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002558 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2559 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002560}
2561
2562void Context::compressedTexImage2D(GLenum target,
2563 GLint level,
2564 GLenum internalformat,
2565 GLsizei width,
2566 GLsizei height,
2567 GLint border,
2568 GLsizei imageSize,
2569 const GLvoid *data)
2570{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002571 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002572
2573 Extents size(width, height, 1);
2574 Texture *texture =
2575 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002576 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2577 size, imageSize,
2578 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002579}
2580
2581void Context::compressedTexImage3D(GLenum target,
2582 GLint level,
2583 GLenum internalformat,
2584 GLsizei width,
2585 GLsizei height,
2586 GLsizei depth,
2587 GLint border,
2588 GLsizei imageSize,
2589 const GLvoid *data)
2590{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002591 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002592
2593 Extents size(width, height, depth);
2594 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002595 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2596 size, imageSize,
2597 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002598}
2599
2600void Context::compressedTexSubImage2D(GLenum target,
2601 GLint level,
2602 GLint xoffset,
2603 GLint yoffset,
2604 GLsizei width,
2605 GLsizei height,
2606 GLenum format,
2607 GLsizei imageSize,
2608 const GLvoid *data)
2609{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002610 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002611
2612 Box area(xoffset, yoffset, 0, width, height, 1);
2613 Texture *texture =
2614 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002615 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2616 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002617}
2618
2619void Context::compressedTexSubImage3D(GLenum target,
2620 GLint level,
2621 GLint xoffset,
2622 GLint yoffset,
2623 GLint zoffset,
2624 GLsizei width,
2625 GLsizei height,
2626 GLsizei depth,
2627 GLenum format,
2628 GLsizei imageSize,
2629 const GLvoid *data)
2630{
2631 // Zero sized uploads are valid but no-ops
2632 if (width == 0 || height == 0)
2633 {
2634 return;
2635 }
2636
Jamie Madillad9f24e2016-02-12 09:27:24 -05002637 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002638
2639 Box area(xoffset, yoffset, zoffset, width, height, depth);
2640 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002641 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2642 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002643}
2644
Olli Etuaho4f667482016-03-30 15:56:35 +03002645void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2646{
2647 Buffer *buffer = getState().getTargetBuffer(target);
2648 ASSERT(buffer);
2649
2650 if (!buffer->isMapped())
2651 {
2652 *params = nullptr;
2653 }
2654 else
2655 {
2656 *params = buffer->getMapPointer();
2657 }
2658}
2659
2660GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2661{
2662 Buffer *buffer = getState().getTargetBuffer(target);
2663 ASSERT(buffer);
2664
2665 Error error = buffer->map(access);
2666 if (error.isError())
2667 {
Jamie Madill437fa652016-05-03 15:13:24 -04002668 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002669 return nullptr;
2670 }
2671
2672 return buffer->getMapPointer();
2673}
2674
2675GLboolean Context::unmapBuffer(GLenum target)
2676{
2677 Buffer *buffer = getState().getTargetBuffer(target);
2678 ASSERT(buffer);
2679
2680 GLboolean result;
2681 Error error = buffer->unmap(&result);
2682 if (error.isError())
2683 {
Jamie Madill437fa652016-05-03 15:13:24 -04002684 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002685 return GL_FALSE;
2686 }
2687
2688 return result;
2689}
2690
2691GLvoid *Context::mapBufferRange(GLenum target,
2692 GLintptr offset,
2693 GLsizeiptr length,
2694 GLbitfield access)
2695{
2696 Buffer *buffer = getState().getTargetBuffer(target);
2697 ASSERT(buffer);
2698
2699 Error error = buffer->mapRange(offset, length, access);
2700 if (error.isError())
2701 {
Jamie Madill437fa652016-05-03 15:13:24 -04002702 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002703 return nullptr;
2704 }
2705
2706 return buffer->getMapPointer();
2707}
2708
2709void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2710{
2711 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2712}
2713
Jamie Madillad9f24e2016-02-12 09:27:24 -05002714void Context::syncStateForReadPixels()
2715{
2716 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2717}
2718
2719void Context::syncStateForTexImage()
2720{
2721 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2722}
2723
2724void Context::syncStateForClear()
2725{
2726 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2727}
2728
2729void Context::syncStateForBlit()
2730{
2731 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2732}
2733
Jamie Madillc29968b2016-01-20 11:17:23 -05002734} // namespace gl