blob: ab25be8959c836ba70486c603da6f519b09d5c80 [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;
Geoff Langb66a9092016-05-16 15:59:14 -04002092 mExtensions.eglImageExternalEssl3 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002093 }
2094
2095 if (clientVersion > 2)
2096 {
2097 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2098 //mExtensions.sRGB = false;
2099 }
2100
Geoff Lang70d0f492015-12-10 17:45:46 -05002101 // Explicitly enable GL_KHR_debug
2102 mExtensions.debug = true;
2103 mExtensions.maxDebugMessageLength = 1024;
2104 mExtensions.maxDebugLoggedMessages = 1024;
2105 mExtensions.maxDebugGroupStackDepth = 1024;
2106 mExtensions.maxLabelLength = 1024;
2107
Geoff Lang301d1612014-07-09 10:34:37 -04002108 // Apply implementation limits
2109 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002110 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2111 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2112
2113 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002114
Geoff Lang900013c2014-07-07 11:32:19 -04002115 mCaps.compressedTextureFormats.clear();
2116
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002117 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002118 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2119 {
2120 GLenum format = i->first;
2121 TextureCaps formatCaps = i->second;
2122
Geoff Lang5d601382014-07-22 15:14:06 -04002123 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002124
Geoff Lang0d8b7242015-09-09 14:56:53 -04002125 // Update the format caps based on the client version and extensions.
2126 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2127 // ES3.
2128 formatCaps.texturable =
2129 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2130 formatCaps.renderable =
2131 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2132 formatCaps.filterable =
2133 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002134
2135 // OpenGL ES does not support multisampling with integer formats
2136 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002137 {
Geoff Langd87878e2014-09-19 15:42:59 -04002138 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002139 }
Geoff Langd87878e2014-09-19 15:42:59 -04002140
2141 if (formatCaps.texturable && formatInfo.compressed)
2142 {
2143 mCaps.compressedTextureFormats.push_back(format);
2144 }
2145
2146 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002147 }
2148}
2149
Jamie Madill1b94d432015-08-07 13:23:23 -04002150void Context::syncRendererState()
2151{
2152 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002153 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002154 mState.clearDirtyBits();
2155 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002156}
2157
Jamie Madillad9f24e2016-02-12 09:27:24 -05002158void Context::syncRendererState(const State::DirtyBits &bitMask,
2159 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002160{
2161 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002162 mImplementation->syncState(mState, dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002163 mState.clearDirtyBits(dirtyBits);
2164
Jamie Madillad9f24e2016-02-12 09:27:24 -05002165 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002166}
Jamie Madillc29968b2016-01-20 11:17:23 -05002167
2168void Context::blitFramebuffer(GLint srcX0,
2169 GLint srcY0,
2170 GLint srcX1,
2171 GLint srcY1,
2172 GLint dstX0,
2173 GLint dstY0,
2174 GLint dstX1,
2175 GLint dstY1,
2176 GLbitfield mask,
2177 GLenum filter)
2178{
Jamie Madillc29968b2016-01-20 11:17:23 -05002179 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2180 ASSERT(drawFramebuffer);
2181
2182 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2183 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2184
Jamie Madillad9f24e2016-02-12 09:27:24 -05002185 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002186
Jamie Madill8415b5f2016-04-26 13:41:39 -04002187 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002188}
Jamie Madillc29968b2016-01-20 11:17:23 -05002189
2190void Context::clear(GLbitfield mask)
2191{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002192 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002193 handleError(mState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002194}
2195
2196void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2197{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002198 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002199 handleError(mState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2200 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002201}
2202
2203void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2204{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002205 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002206 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2207 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002208}
2209
2210void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2211{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002212 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002213 handleError(mState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2214 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002215}
2216
2217void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2218{
2219 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2220 ASSERT(framebufferObject);
2221
2222 // If a buffer is not present, the clear has no effect
2223 if (framebufferObject->getDepthbuffer() == nullptr &&
2224 framebufferObject->getStencilbuffer() == nullptr)
2225 {
2226 return;
2227 }
2228
Jamie Madillad9f24e2016-02-12 09:27:24 -05002229 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002230 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2231 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002232}
2233
2234void Context::readPixels(GLint x,
2235 GLint y,
2236 GLsizei width,
2237 GLsizei height,
2238 GLenum format,
2239 GLenum type,
2240 GLvoid *pixels)
2241{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002242 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002243
2244 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2245 ASSERT(framebufferObject);
2246
2247 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002248 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002249}
2250
2251void Context::copyTexImage2D(GLenum target,
2252 GLint level,
2253 GLenum internalformat,
2254 GLint x,
2255 GLint y,
2256 GLsizei width,
2257 GLsizei height,
2258 GLint border)
2259{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002260 // Only sync the read FBO
2261 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2262
Jamie Madillc29968b2016-01-20 11:17:23 -05002263 Rectangle sourceArea(x, y, width, height);
2264
2265 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2266 Texture *texture =
2267 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002268 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002269}
2270
2271void Context::copyTexSubImage2D(GLenum target,
2272 GLint level,
2273 GLint xoffset,
2274 GLint yoffset,
2275 GLint x,
2276 GLint y,
2277 GLsizei width,
2278 GLsizei height)
2279{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002280 // Only sync the read FBO
2281 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2282
Jamie Madillc29968b2016-01-20 11:17:23 -05002283 Offset destOffset(xoffset, yoffset, 0);
2284 Rectangle sourceArea(x, y, width, height);
2285
2286 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2287 Texture *texture =
2288 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002289 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002290}
2291
2292void Context::copyTexSubImage3D(GLenum target,
2293 GLint level,
2294 GLint xoffset,
2295 GLint yoffset,
2296 GLint zoffset,
2297 GLint x,
2298 GLint y,
2299 GLsizei width,
2300 GLsizei height)
2301{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002302 // Only sync the read FBO
2303 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2304
Jamie Madillc29968b2016-01-20 11:17:23 -05002305 Offset destOffset(xoffset, yoffset, zoffset);
2306 Rectangle sourceArea(x, y, width, height);
2307
2308 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2309 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002310 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002311}
2312
2313void Context::framebufferTexture2D(GLenum target,
2314 GLenum attachment,
2315 GLenum textarget,
2316 GLuint texture,
2317 GLint level)
2318{
2319 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2320 ASSERT(framebuffer);
2321
2322 if (texture != 0)
2323 {
2324 Texture *textureObj = getTexture(texture);
2325
2326 ImageIndex index = ImageIndex::MakeInvalid();
2327
2328 if (textarget == GL_TEXTURE_2D)
2329 {
2330 index = ImageIndex::Make2D(level);
2331 }
2332 else
2333 {
2334 ASSERT(IsCubeMapTextureTarget(textarget));
2335 index = ImageIndex::MakeCube(textarget, level);
2336 }
2337
2338 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2339 }
2340 else
2341 {
2342 framebuffer->resetAttachment(attachment);
2343 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002344
2345 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002346}
2347
2348void Context::framebufferRenderbuffer(GLenum target,
2349 GLenum attachment,
2350 GLenum renderbuffertarget,
2351 GLuint renderbuffer)
2352{
2353 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2354 ASSERT(framebuffer);
2355
2356 if (renderbuffer != 0)
2357 {
2358 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2359 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2360 renderbufferObject);
2361 }
2362 else
2363 {
2364 framebuffer->resetAttachment(attachment);
2365 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002366
2367 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002368}
2369
2370void Context::framebufferTextureLayer(GLenum target,
2371 GLenum attachment,
2372 GLuint texture,
2373 GLint level,
2374 GLint layer)
2375{
2376 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2377 ASSERT(framebuffer);
2378
2379 if (texture != 0)
2380 {
2381 Texture *textureObject = getTexture(texture);
2382
2383 ImageIndex index = ImageIndex::MakeInvalid();
2384
2385 if (textureObject->getTarget() == GL_TEXTURE_3D)
2386 {
2387 index = ImageIndex::Make3D(level, layer);
2388 }
2389 else
2390 {
2391 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2392 index = ImageIndex::Make2DArray(level, layer);
2393 }
2394
2395 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2396 }
2397 else
2398 {
2399 framebuffer->resetAttachment(attachment);
2400 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002401
2402 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002403}
2404
2405void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2406{
2407 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2408 ASSERT(framebuffer);
2409 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002410 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002411}
2412
2413void Context::readBuffer(GLenum mode)
2414{
2415 Framebuffer *readFBO = mState.getReadFramebuffer();
2416 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002417 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002418}
2419
2420void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2421{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002422 // Only sync the FBO
2423 mState.syncDirtyObject(target);
2424
Jamie Madillc29968b2016-01-20 11:17:23 -05002425 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2426 ASSERT(framebuffer);
2427
2428 // The specification isn't clear what should be done when the framebuffer isn't complete.
2429 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002430 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002431}
2432
2433void Context::invalidateFramebuffer(GLenum target,
2434 GLsizei numAttachments,
2435 const GLenum *attachments)
2436{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002437 // Only sync the FBO
2438 mState.syncDirtyObject(target);
2439
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2441 ASSERT(framebuffer);
2442
Jamie Madill437fa652016-05-03 15:13:24 -04002443 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002444 {
Jamie Madill437fa652016-05-03 15:13:24 -04002445 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 }
Jamie Madill437fa652016-05-03 15:13:24 -04002447
2448 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002449}
2450
2451void Context::invalidateSubFramebuffer(GLenum target,
2452 GLsizei numAttachments,
2453 const GLenum *attachments,
2454 GLint x,
2455 GLint y,
2456 GLsizei width,
2457 GLsizei height)
2458{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002459 // Only sync the FBO
2460 mState.syncDirtyObject(target);
2461
Jamie Madillc29968b2016-01-20 11:17:23 -05002462 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2463 ASSERT(framebuffer);
2464
Jamie Madill437fa652016-05-03 15:13:24 -04002465 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002466 {
Jamie Madill437fa652016-05-03 15:13:24 -04002467 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002468 }
Jamie Madill437fa652016-05-03 15:13:24 -04002469
2470 Rectangle area(x, y, width, height);
2471 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002472}
2473
Jamie Madill73a84962016-02-12 09:27:23 -05002474void Context::texImage2D(GLenum target,
2475 GLint level,
2476 GLint internalformat,
2477 GLsizei width,
2478 GLsizei height,
2479 GLint border,
2480 GLenum format,
2481 GLenum type,
2482 const GLvoid *pixels)
2483{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002484 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002485
2486 Extents size(width, height, 1);
2487 Texture *texture =
2488 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002489 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2490 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002491}
2492
2493void Context::texImage3D(GLenum target,
2494 GLint level,
2495 GLint internalformat,
2496 GLsizei width,
2497 GLsizei height,
2498 GLsizei depth,
2499 GLint border,
2500 GLenum format,
2501 GLenum type,
2502 const GLvoid *pixels)
2503{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002504 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002505
2506 Extents size(width, height, depth);
2507 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002508 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2509 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002510}
2511
2512void Context::texSubImage2D(GLenum target,
2513 GLint level,
2514 GLint xoffset,
2515 GLint yoffset,
2516 GLsizei width,
2517 GLsizei height,
2518 GLenum format,
2519 GLenum type,
2520 const GLvoid *pixels)
2521{
2522 // Zero sized uploads are valid but no-ops
2523 if (width == 0 || height == 0)
2524 {
2525 return;
2526 }
2527
Jamie Madillad9f24e2016-02-12 09:27:24 -05002528 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002529
2530 Box area(xoffset, yoffset, 0, width, height, 1);
2531 Texture *texture =
2532 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002533 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2534 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002535}
2536
2537void Context::texSubImage3D(GLenum target,
2538 GLint level,
2539 GLint xoffset,
2540 GLint yoffset,
2541 GLint zoffset,
2542 GLsizei width,
2543 GLsizei height,
2544 GLsizei depth,
2545 GLenum format,
2546 GLenum type,
2547 const GLvoid *pixels)
2548{
2549 // Zero sized uploads are valid but no-ops
2550 if (width == 0 || height == 0 || depth == 0)
2551 {
2552 return;
2553 }
2554
Jamie Madillad9f24e2016-02-12 09:27:24 -05002555 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002556
2557 Box area(xoffset, yoffset, zoffset, width, height, depth);
2558 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002559 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2560 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002561}
2562
2563void Context::compressedTexImage2D(GLenum target,
2564 GLint level,
2565 GLenum internalformat,
2566 GLsizei width,
2567 GLsizei height,
2568 GLint border,
2569 GLsizei imageSize,
2570 const GLvoid *data)
2571{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002572 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002573
2574 Extents size(width, height, 1);
2575 Texture *texture =
2576 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002577 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2578 size, imageSize,
2579 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002580}
2581
2582void Context::compressedTexImage3D(GLenum target,
2583 GLint level,
2584 GLenum internalformat,
2585 GLsizei width,
2586 GLsizei height,
2587 GLsizei depth,
2588 GLint border,
2589 GLsizei imageSize,
2590 const GLvoid *data)
2591{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002592 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002593
2594 Extents size(width, height, depth);
2595 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002596 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2597 size, imageSize,
2598 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002599}
2600
2601void Context::compressedTexSubImage2D(GLenum target,
2602 GLint level,
2603 GLint xoffset,
2604 GLint yoffset,
2605 GLsizei width,
2606 GLsizei height,
2607 GLenum format,
2608 GLsizei imageSize,
2609 const GLvoid *data)
2610{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002611 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002612
2613 Box area(xoffset, yoffset, 0, width, height, 1);
2614 Texture *texture =
2615 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002616 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2617 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002618}
2619
2620void Context::compressedTexSubImage3D(GLenum target,
2621 GLint level,
2622 GLint xoffset,
2623 GLint yoffset,
2624 GLint zoffset,
2625 GLsizei width,
2626 GLsizei height,
2627 GLsizei depth,
2628 GLenum format,
2629 GLsizei imageSize,
2630 const GLvoid *data)
2631{
2632 // Zero sized uploads are valid but no-ops
2633 if (width == 0 || height == 0)
2634 {
2635 return;
2636 }
2637
Jamie Madillad9f24e2016-02-12 09:27:24 -05002638 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002639
2640 Box area(xoffset, yoffset, zoffset, width, height, depth);
2641 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002642 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2643 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002644}
2645
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002646void Context::generateMipmap(GLenum target)
2647{
2648 Texture *texture = getTargetTexture(target);
2649 handleError(texture->generateMipmap());
2650}
2651
Olli Etuaho4f667482016-03-30 15:56:35 +03002652void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2653{
2654 Buffer *buffer = getState().getTargetBuffer(target);
2655 ASSERT(buffer);
2656
2657 if (!buffer->isMapped())
2658 {
2659 *params = nullptr;
2660 }
2661 else
2662 {
2663 *params = buffer->getMapPointer();
2664 }
2665}
2666
2667GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2668{
2669 Buffer *buffer = getState().getTargetBuffer(target);
2670 ASSERT(buffer);
2671
2672 Error error = buffer->map(access);
2673 if (error.isError())
2674 {
Jamie Madill437fa652016-05-03 15:13:24 -04002675 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002676 return nullptr;
2677 }
2678
2679 return buffer->getMapPointer();
2680}
2681
2682GLboolean Context::unmapBuffer(GLenum target)
2683{
2684 Buffer *buffer = getState().getTargetBuffer(target);
2685 ASSERT(buffer);
2686
2687 GLboolean result;
2688 Error error = buffer->unmap(&result);
2689 if (error.isError())
2690 {
Jamie Madill437fa652016-05-03 15:13:24 -04002691 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002692 return GL_FALSE;
2693 }
2694
2695 return result;
2696}
2697
2698GLvoid *Context::mapBufferRange(GLenum target,
2699 GLintptr offset,
2700 GLsizeiptr length,
2701 GLbitfield access)
2702{
2703 Buffer *buffer = getState().getTargetBuffer(target);
2704 ASSERT(buffer);
2705
2706 Error error = buffer->mapRange(offset, length, access);
2707 if (error.isError())
2708 {
Jamie Madill437fa652016-05-03 15:13:24 -04002709 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002710 return nullptr;
2711 }
2712
2713 return buffer->getMapPointer();
2714}
2715
2716void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2717{
2718 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2719}
2720
Jamie Madillad9f24e2016-02-12 09:27:24 -05002721void Context::syncStateForReadPixels()
2722{
2723 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2724}
2725
2726void Context::syncStateForTexImage()
2727{
2728 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2729}
2730
2731void Context::syncStateForClear()
2732{
2733 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2734}
2735
2736void Context::syncStateForBlit()
2737{
2738 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2739}
2740
Jamie Madillc29968b2016-01-20 11:17:23 -05002741} // namespace gl