blob: 2e89b81702c121fe5c45a6dbefd830bad1d50389 [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"
Geoff Lang2b5420c2014-11-19 14:20:15 -050035#include "libANGLE/renderer/Renderer.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
Corentin Wallez51706ea2015-08-07 14:39:22 -0400125Context::Context(const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400126 const Context *shareContext,
127 rx::Renderer *renderer,
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 Madill437fa652016-05-03 15:13:24 -0400137 mImplementation(renderer->createContext()),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mCompiler(nullptr),
Jamie Madillf25855c2015-11-03 11:06:18 -0500139 mRenderer(renderer),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400141 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142 mClientType(EGL_OPENGL_ES_API),
143 mHasBeenCurrent(false),
144 mContextLost(false),
145 mResetStatus(GL_NO_ERROR),
146 mResetStrategy(GetResetStrategy(attribs)),
147 mRobustAccess(GetRobustAccess(attribs)),
148 mCurrentSurface(nullptr),
149 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000150{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000152
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400154
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100156
Shannon Woods53a94a82014-06-24 15:20:36 -0400157 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400158
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000159 if (shareContext != NULL)
160 {
161 mResourceManager = shareContext->mResourceManager;
162 mResourceManager->addRef();
163 }
164 else
165 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000166 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000167 }
168
Jamie Madillc185cb82015-04-28 12:39:08 -0400169 mData.resourceManager = mResourceManager;
170
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000171 // [OpenGL ES 2.0.24] section 3.7 page 83:
172 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
173 // and cube map texture state vectors respectively associated with them.
174 // In order that access to these initial textures not be lost, they are treated as texture
175 // objects all of whose names are 0.
176
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300177 Texture *zeroTexture2D = new Texture(mRenderer, 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500178 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500179
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300180 Texture *zeroTextureCube = new Texture(mRenderer, 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500181 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400182
183 if (mClientVersion >= 3)
184 {
185 // TODO: These could also be enabled via extension
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300186 Texture *zeroTexture3D = new Texture(mRenderer, 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500187 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400188
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300189 Texture *zeroTexture2DArray = new Texture(mRenderer, 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500190 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400191 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000192
Ian Ewellbda75592016-04-18 17:25:54 -0400193 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
194 {
195 Texture *zeroTextureExternal = new Texture(mRenderer, 0, GL_TEXTURE_EXTERNAL_OES);
196 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 Madill83f349e2015-09-23 09:50:36 -0400227 mCompiler = new Compiler(mRenderer, 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
267 handleError(mImplementation->initialize(renderer));
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
369 mRenderer->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 Madill006cbc52015-09-23 16:47:54 -0400419 return mResourceManager->createShader(mRenderer->getRendererLimitations(), 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
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700472 mFenceNVMap[handle] = new FenceNV(mRenderer->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 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700954 query->second = new Query(mRenderer->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:
1112 *params = mRenderer->getGPUDisjoint();
1113 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:
1145 *params = mRenderer->getTimestamp();
1146 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;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001383 }
1384
Geoff Lang70d0f492015-12-10 17:45:46 -05001385 if (mExtensions.debug)
1386 {
1387 switch (pname)
1388 {
1389 case GL_DEBUG_LOGGED_MESSAGES:
1390 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1391 case GL_DEBUG_GROUP_STACK_DEPTH:
1392 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1393 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1394 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1395 case GL_MAX_LABEL_LENGTH:
1396 *type = GL_INT;
1397 *numParams = 1;
1398 return true;
1399
1400 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1401 case GL_DEBUG_OUTPUT:
1402 *type = GL_BOOL;
1403 *numParams = 1;
1404 return true;
1405 }
1406 }
1407
Austin Kinrossbc781f32015-10-26 09:27:38 -07001408 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1409 switch (pname)
1410 {
1411 case GL_PACK_ROW_LENGTH:
1412 case GL_PACK_SKIP_ROWS:
1413 case GL_PACK_SKIP_PIXELS:
1414 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1415 {
1416 return false;
1417 }
1418 *type = GL_INT;
1419 *numParams = 1;
1420 return true;
1421 case GL_UNPACK_ROW_LENGTH:
1422 case GL_UNPACK_SKIP_ROWS:
1423 case GL_UNPACK_SKIP_PIXELS:
1424 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1425 {
1426 return false;
1427 }
1428 *type = GL_INT;
1429 *numParams = 1;
1430 return true;
1431 case GL_VERTEX_ARRAY_BINDING:
1432 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1433 {
1434 return false;
1435 }
1436 *type = GL_INT;
1437 *numParams = 1;
1438 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001439 case GL_PIXEL_PACK_BUFFER_BINDING:
1440 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1441 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1442 {
1443 return false;
1444 }
1445 *type = GL_INT;
1446 *numParams = 1;
1447 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001448 }
1449
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001450 if (mClientVersion < 3)
1451 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001452 return false;
1453 }
1454
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001455 // Check for ES3.0+ parameter names
1456 switch (pname)
1457 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001458 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1459 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001460 case GL_UNIFORM_BUFFER_BINDING:
1461 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001462 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001463 case GL_COPY_READ_BUFFER_BINDING:
1464 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001465 case GL_SAMPLER_BINDING:
1466 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001467 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001468 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001469 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001470 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001471 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1472 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1473 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001474 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1475 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001476 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001477 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1478 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001479 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1480 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001481 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001482 case GL_MAJOR_VERSION:
1483 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001484 case GL_MAX_ELEMENTS_INDICES:
1485 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001486 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001487 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001488 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001489 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001490 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001491 {
1492 *type = GL_INT;
1493 *numParams = 1;
1494 }
1495 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001496
1497 case GL_MAX_ELEMENT_INDEX:
1498 case GL_MAX_UNIFORM_BLOCK_SIZE:
1499 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1500 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1501 case GL_MAX_SERVER_WAIT_TIMEOUT:
1502 {
1503 *type = GL_INT_64_ANGLEX;
1504 *numParams = 1;
1505 }
1506 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001507
1508 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001509 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001510 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001511 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001512 {
1513 *type = GL_BOOL;
1514 *numParams = 1;
1515 }
1516 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001517
1518 case GL_MAX_TEXTURE_LOD_BIAS:
1519 {
1520 *type = GL_FLOAT;
1521 *numParams = 1;
1522 }
1523 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001524 }
1525
1526 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001527}
1528
Shannon Woods1b2fb852013-08-19 14:28:48 -04001529bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1530{
1531 if (mClientVersion < 3)
1532 {
1533 return false;
1534 }
1535
1536 switch (target)
1537 {
1538 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1539 case GL_UNIFORM_BUFFER_BINDING:
1540 {
1541 *type = GL_INT;
1542 *numParams = 1;
1543 }
1544 return true;
1545 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1546 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1547 case GL_UNIFORM_BUFFER_START:
1548 case GL_UNIFORM_BUFFER_SIZE:
1549 {
1550 *type = GL_INT_64_ANGLEX;
1551 *numParams = 1;
1552 }
1553 }
1554
1555 return false;
1556}
1557
Geoff Langf6db0982015-08-25 13:04:00 -04001558Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001559{
Jamie Madill1b94d432015-08-07 13:23:23 -04001560 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001561 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001562 if (error.isError())
1563 {
1564 return error;
1565 }
1566
Geoff Langf6db0982015-08-25 13:04:00 -04001567 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001568
1569 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001570}
1571
Geoff Langf6db0982015-08-25 13:04:00 -04001572Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1573{
1574 syncRendererState();
1575 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1576 if (error.isError())
1577 {
1578 return error;
1579 }
1580
1581 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1582
1583 return Error(GL_NO_ERROR);
1584}
1585
1586Error Context::drawElements(GLenum mode,
1587 GLsizei count,
1588 GLenum type,
1589 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001590 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001591{
Jamie Madill1b94d432015-08-07 13:23:23 -04001592 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001593 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1594}
1595
1596Error Context::drawElementsInstanced(GLenum mode,
1597 GLsizei count,
1598 GLenum type,
1599 const GLvoid *indices,
1600 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001601 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001602{
1603 syncRendererState();
1604 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1605 indexRange);
1606}
1607
1608Error Context::drawRangeElements(GLenum mode,
1609 GLuint start,
1610 GLuint end,
1611 GLsizei count,
1612 GLenum type,
1613 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001614 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001615{
1616 syncRendererState();
1617 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1618 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619}
1620
Geoff Lang129753a2015-01-09 16:52:09 -05001621Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001622{
Geoff Lang129753a2015-01-09 16:52:09 -05001623 return mRenderer->flush();
1624}
1625
1626Error Context::finish()
1627{
1628 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629}
1630
Austin Kinross6ee1e782015-05-29 17:05:37 -07001631void Context::insertEventMarker(GLsizei length, const char *marker)
1632{
1633 ASSERT(mRenderer);
1634 mRenderer->insertEventMarker(length, marker);
1635}
1636
1637void Context::pushGroupMarker(GLsizei length, const char *marker)
1638{
1639 ASSERT(mRenderer);
1640 mRenderer->pushGroupMarker(length, marker);
1641}
1642
1643void Context::popGroupMarker()
1644{
1645 ASSERT(mRenderer);
1646 mRenderer->popGroupMarker();
1647}
1648
Geoff Langd8605522016-04-13 10:19:12 -04001649void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1650{
1651 Program *programObject = getProgram(program);
1652 ASSERT(programObject);
1653
1654 programObject->bindUniformLocation(location, name);
1655}
1656
Jamie Madill437fa652016-05-03 15:13:24 -04001657void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001658{
Geoff Langda5777c2014-07-11 09:52:58 -04001659 if (error.isError())
1660 {
1661 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001662
1663 if (!error.getMessage().empty())
1664 {
1665 auto &debug = mState.getDebug();
1666 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1667 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1668 }
Geoff Langda5777c2014-07-11 09:52:58 -04001669 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001670}
1671
1672// Get one of the recorded errors and clear its flag, if any.
1673// [OpenGL ES 2.0.24] section 2.5 page 13.
1674GLenum Context::getError()
1675{
Geoff Langda5777c2014-07-11 09:52:58 -04001676 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001677 {
Geoff Langda5777c2014-07-11 09:52:58 -04001678 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001679 }
Geoff Langda5777c2014-07-11 09:52:58 -04001680 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001681 {
Geoff Langda5777c2014-07-11 09:52:58 -04001682 GLenum error = *mErrors.begin();
1683 mErrors.erase(mErrors.begin());
1684 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001685 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686}
1687
1688GLenum Context::getResetStatus()
1689{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001690 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001691 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001692 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001693 // mResetStatus will be set by the markContextLost callback
1694 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001695 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001696 {
1697 mRenderer->notifyDeviceLost();
1698 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001699 }
1700
1701 GLenum status = mResetStatus;
1702
1703 if (mResetStatus != GL_NO_ERROR)
1704 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001705 ASSERT(mContextLost);
1706
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001707 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001708 {
1709 mResetStatus = GL_NO_ERROR;
1710 }
1711 }
Jamie Madill893ab082014-05-16 16:56:10 -04001712
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001713 return status;
1714}
1715
1716bool Context::isResetNotificationEnabled()
1717{
1718 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1719}
1720
Corentin Walleze3b10e82015-05-20 11:06:25 -04001721const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001722{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001723 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001724}
1725
1726EGLenum Context::getClientType() const
1727{
1728 return mClientType;
1729}
1730
1731EGLenum Context::getRenderBuffer() const
1732{
Corentin Wallez37c39792015-08-20 14:19:46 -04001733 auto framebufferIt = mFramebufferMap.find(0);
1734 if (framebufferIt != mFramebufferMap.end())
1735 {
1736 const Framebuffer *framebuffer = framebufferIt->second;
1737 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1738
1739 ASSERT(backAttachment != nullptr);
1740 return backAttachment->getSurface()->getRenderBuffer();
1741 }
1742 else
1743 {
1744 return EGL_NONE;
1745 }
Régis Fénéon83107972015-02-05 12:57:44 +01001746}
1747
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001748VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001749{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001750 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001751 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1752 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001753 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001754 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1755 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001756 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001757
1758 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001759}
1760
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001761TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001762{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001763 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001764 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1765 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001766 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001767 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1768 transformFeedback->addRef();
1769 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001770 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001771
1772 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001773}
1774
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001775Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1776{
1777 // Can be called from Bind without a prior call to Gen.
1778 auto framebufferIt = mFramebufferMap.find(framebuffer);
1779 bool neverCreated = framebufferIt == mFramebufferMap.end();
1780 if (neverCreated || framebufferIt->second == nullptr)
1781 {
1782 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1783 if (neverCreated)
1784 {
1785 mFramebufferHandleAllocator.reserve(framebuffer);
1786 mFramebufferMap[framebuffer] = newFBO;
1787 return newFBO;
1788 }
1789
1790 framebufferIt->second = newFBO;
1791 }
1792
1793 return framebufferIt->second;
1794}
1795
Geoff Lang36167ab2015-12-07 10:27:14 -05001796bool Context::isVertexArrayGenerated(GLuint vertexArray)
1797{
1798 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1799}
1800
1801bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1802{
1803 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1804}
1805
Shannon Woods53a94a82014-06-24 15:20:36 -04001806void Context::detachTexture(GLuint texture)
1807{
1808 // Simple pass-through to State's detachTexture method, as textures do not require
1809 // allocation map management either here or in the resource manager at detach time.
1810 // Zero textures are held by the Context, and we don't attempt to request them from
1811 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001812 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001813}
1814
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001815void Context::detachBuffer(GLuint buffer)
1816{
Yuly Novikov5807a532015-12-03 13:01:22 -05001817 // Simple pass-through to State's detachBuffer method, since
1818 // only buffer attachments to container objects that are bound to the current context
1819 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001820
Yuly Novikov5807a532015-12-03 13:01:22 -05001821 // [OpenGL ES 3.2] section 5.1.2 page 45:
1822 // Attachments to unbound container objects, such as
1823 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1824 // are not affected and continue to act as references on the deleted object
1825 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001826}
1827
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001828void Context::detachFramebuffer(GLuint framebuffer)
1829{
Shannon Woods53a94a82014-06-24 15:20:36 -04001830 // Framebuffer detachment is handled by Context, because 0 is a valid
1831 // Framebuffer object, and a pointer to it must be passed from Context
1832 // to State at binding time.
1833
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001834 // [OpenGL ES 2.0.24] section 4.4 page 107:
1835 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1836 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1837
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001838 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001839 {
1840 bindReadFramebuffer(0);
1841 }
1842
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001843 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001844 {
1845 bindDrawFramebuffer(0);
1846 }
1847}
1848
1849void Context::detachRenderbuffer(GLuint renderbuffer)
1850{
Shannon Woods53a94a82014-06-24 15:20:36 -04001851 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001852}
1853
Jamie Madill57a89722013-07-02 11:57:03 -04001854void Context::detachVertexArray(GLuint vertexArray)
1855{
Jamie Madill77a72f62015-04-14 11:18:32 -04001856 // Vertex array detachment is handled by Context, because 0 is a valid
1857 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001858 // binding time.
1859
Jamie Madill57a89722013-07-02 11:57:03 -04001860 // [OpenGL ES 3.0.2] section 2.10 page 43:
1861 // If a vertex array object that is currently bound is deleted, the binding
1862 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001863 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001864 {
1865 bindVertexArray(0);
1866 }
1867}
1868
Geoff Langc8058452014-02-03 12:04:11 -05001869void Context::detachTransformFeedback(GLuint transformFeedback)
1870{
Corentin Walleza2257da2016-04-19 16:43:12 -04001871 // Transform feedback detachment is handled by Context, because 0 is a valid
1872 // transform feedback, and a pointer to it must be passed from Context to State at
1873 // binding time.
1874
1875 // The OpenGL specification doesn't mention what should happen when the currently bound
1876 // transform feedback object is deleted. Since it is a container object, we treat it like
1877 // VAOs and FBOs and set the current bound transform feedback back to 0.
1878 if (mState.removeTransformFeedbackBinding(transformFeedback))
1879 {
1880 bindTransformFeedback(0);
1881 }
Geoff Langc8058452014-02-03 12:04:11 -05001882}
1883
Jamie Madilldc356042013-07-19 16:36:57 -04001884void Context::detachSampler(GLuint sampler)
1885{
Shannon Woods53a94a82014-06-24 15:20:36 -04001886 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001887}
1888
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001889void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1890{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001891 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001892}
1893
Jamie Madille29d1672013-07-19 16:36:57 -04001894void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1895{
1896 mResourceManager->checkSamplerAllocation(sampler);
1897
1898 Sampler *samplerObject = getSampler(sampler);
1899 ASSERT(samplerObject);
1900
Geoff Lang69cce582015-09-17 13:20:36 -04001901 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001902 switch (pname)
1903 {
Geoff Lang69cce582015-09-17 13:20:36 -04001904 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1905 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1906 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1907 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1908 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1909 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1910 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1911 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1912 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1913 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1914 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001915 }
Geoff Lang69cce582015-09-17 13:20:36 -04001916 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001917}
1918
1919void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1920{
1921 mResourceManager->checkSamplerAllocation(sampler);
1922
1923 Sampler *samplerObject = getSampler(sampler);
1924 ASSERT(samplerObject);
1925
Geoff Lang69cce582015-09-17 13:20:36 -04001926 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001927 switch (pname)
1928 {
Geoff Lang69cce582015-09-17 13:20:36 -04001929 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1930 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1931 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1932 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1933 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1934 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1935 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1936 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1937 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1938 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1939 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001940 }
Geoff Lang69cce582015-09-17 13:20:36 -04001941 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001942}
1943
Jamie Madill9675b802013-07-19 16:36:59 -04001944GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1945{
1946 mResourceManager->checkSamplerAllocation(sampler);
1947
1948 Sampler *samplerObject = getSampler(sampler);
1949 ASSERT(samplerObject);
1950
Geoff Lang69cce582015-09-17 13:20:36 -04001951 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001952 switch (pname)
1953 {
Geoff Lang69cce582015-09-17 13:20:36 -04001954 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1955 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1956 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1957 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1958 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1959 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001960 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1961 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001962 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1963 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1964 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001965 }
Geoff Lang69cce582015-09-17 13:20:36 -04001966 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001967}
1968
1969GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1970{
1971 mResourceManager->checkSamplerAllocation(sampler);
1972
1973 Sampler *samplerObject = getSampler(sampler);
1974 ASSERT(samplerObject);
1975
Geoff Lang69cce582015-09-17 13:20:36 -04001976 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001977 switch (pname)
1978 {
Geoff Lang69cce582015-09-17 13:20:36 -04001979 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1980 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1981 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1982 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1983 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1984 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1985 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1986 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1987 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1988 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1989 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001990 }
Geoff Lang69cce582015-09-17 13:20:36 -04001991 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001992}
1993
Olli Etuahof0fee072016-03-30 15:11:58 +03001994void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1995{
1996 gl::Program *programObject = getProgram(program);
1997 ASSERT(programObject != nullptr);
1998
1999 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2000 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2001}
2002
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002003void Context::initRendererString()
2004{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002005 std::ostringstream rendererString;
2006 rendererString << "ANGLE (";
2007 rendererString << mRenderer->getRendererDescription();
2008 rendererString << ")";
2009
Geoff Langcec35902014-04-16 10:52:36 -04002010 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002011}
2012
Geoff Langc0b9ef42014-07-02 10:02:37 -04002013const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002014{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002015 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002016}
2017
Geoff Langcec35902014-04-16 10:52:36 -04002018void Context::initExtensionStrings()
2019{
Geoff Lang493daf52014-07-03 13:38:44 -04002020 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002021
Geoff Langc0b9ef42014-07-02 10:02:37 -04002022 std::ostringstream combinedStringStream;
2023 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2024 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002025}
2026
Geoff Langc0b9ef42014-07-02 10:02:37 -04002027const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002028{
2029 return mExtensionString;
2030}
2031
Geoff Langc0b9ef42014-07-02 10:02:37 -04002032const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002033{
2034 return mExtensionStrings[idx];
2035}
2036
2037size_t Context::getExtensionStringCount() const
2038{
2039 return mExtensionStrings.size();
2040}
2041
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002042void Context::beginTransformFeedback(GLenum primitiveMode)
2043{
2044 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2045 ASSERT(transformFeedback != nullptr);
2046 ASSERT(!transformFeedback->isPaused());
2047
2048 transformFeedback->begin(primitiveMode, getState().getProgram());
2049}
2050
2051bool Context::hasActiveTransformFeedback(GLuint program) const
2052{
2053 for (auto pair : mTransformFeedbackMap)
2054 {
2055 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2056 {
2057 return true;
2058 }
2059 }
2060 return false;
2061}
2062
Geoff Lang493daf52014-07-03 13:38:44 -04002063void Context::initCaps(GLuint clientVersion)
2064{
2065 mCaps = mRenderer->getRendererCaps();
2066
2067 mExtensions = mRenderer->getRendererExtensions();
2068
Austin Kinross02df7962015-07-01 10:03:42 -07002069 mLimitations = mRenderer->getRendererLimitations();
2070
Geoff Lang493daf52014-07-03 13:38:44 -04002071 if (clientVersion < 3)
2072 {
2073 // Disable ES3+ extensions
2074 mExtensions.colorBufferFloat = false;
2075 }
2076
2077 if (clientVersion > 2)
2078 {
2079 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2080 //mExtensions.sRGB = false;
2081 }
2082
Geoff Lang70d0f492015-12-10 17:45:46 -05002083 // Explicitly enable GL_KHR_debug
2084 mExtensions.debug = true;
2085 mExtensions.maxDebugMessageLength = 1024;
2086 mExtensions.maxDebugLoggedMessages = 1024;
2087 mExtensions.maxDebugGroupStackDepth = 1024;
2088 mExtensions.maxLabelLength = 1024;
2089
Geoff Lang301d1612014-07-09 10:34:37 -04002090 // Apply implementation limits
2091 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002092 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2093 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2094
2095 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002096
Geoff Lang900013c2014-07-07 11:32:19 -04002097 mCaps.compressedTextureFormats.clear();
2098
Geoff Lang493daf52014-07-03 13:38:44 -04002099 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2100 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2101 {
2102 GLenum format = i->first;
2103 TextureCaps formatCaps = i->second;
2104
Geoff Lang5d601382014-07-22 15:14:06 -04002105 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002106
Geoff Lang0d8b7242015-09-09 14:56:53 -04002107 // Update the format caps based on the client version and extensions.
2108 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2109 // ES3.
2110 formatCaps.texturable =
2111 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2112 formatCaps.renderable =
2113 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2114 formatCaps.filterable =
2115 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002116
2117 // OpenGL ES does not support multisampling with integer formats
2118 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002119 {
Geoff Langd87878e2014-09-19 15:42:59 -04002120 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002121 }
Geoff Langd87878e2014-09-19 15:42:59 -04002122
2123 if (formatCaps.texturable && formatInfo.compressed)
2124 {
2125 mCaps.compressedTextureFormats.push_back(format);
2126 }
2127
2128 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002129 }
2130}
2131
Jamie Madill1b94d432015-08-07 13:23:23 -04002132void Context::syncRendererState()
2133{
2134 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002135 mRenderer->syncState(mState, dirtyBits);
2136 mState.clearDirtyBits();
2137 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002138}
2139
Jamie Madillad9f24e2016-02-12 09:27:24 -05002140void Context::syncRendererState(const State::DirtyBits &bitMask,
2141 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002142{
2143 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002144 mRenderer->syncState(mState, dirtyBits);
2145 mState.clearDirtyBits(dirtyBits);
2146
Jamie Madillad9f24e2016-02-12 09:27:24 -05002147 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002148}
Jamie Madillc29968b2016-01-20 11:17:23 -05002149
2150void Context::blitFramebuffer(GLint srcX0,
2151 GLint srcY0,
2152 GLint srcX1,
2153 GLint srcY1,
2154 GLint dstX0,
2155 GLint dstY0,
2156 GLint dstX1,
2157 GLint dstY1,
2158 GLbitfield mask,
2159 GLenum filter)
2160{
2161 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2162 ASSERT(readFramebuffer);
2163
2164 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2165 ASSERT(drawFramebuffer);
2166
2167 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2168 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2169
Jamie Madillad9f24e2016-02-12 09:27:24 -05002170 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002171
Jamie Madill437fa652016-05-03 15:13:24 -04002172 handleError(drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002173}
Jamie Madillc29968b2016-01-20 11:17:23 -05002174
2175void Context::clear(GLbitfield mask)
2176{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002177 syncStateForClear();
Jamie Madill437fa652016-05-03 15:13:24 -04002178 handleError(mState.getDrawFramebuffer()->clear(mData, mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002179}
2180
2181void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2182{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002183 syncStateForClear();
Jamie Madill437fa652016-05-03 15:13:24 -04002184 handleError(mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002185}
2186
2187void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2188{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002189 syncStateForClear();
Jamie Madill437fa652016-05-03 15:13:24 -04002190 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002191}
2192
2193void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2194{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002195 syncStateForClear();
Jamie Madill437fa652016-05-03 15:13:24 -04002196 handleError(mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002197}
2198
2199void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2200{
2201 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2202 ASSERT(framebufferObject);
2203
2204 // If a buffer is not present, the clear has no effect
2205 if (framebufferObject->getDepthbuffer() == nullptr &&
2206 framebufferObject->getStencilbuffer() == nullptr)
2207 {
2208 return;
2209 }
2210
Jamie Madillad9f24e2016-02-12 09:27:24 -05002211 syncStateForClear();
Jamie Madill437fa652016-05-03 15:13:24 -04002212 handleError(framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002213}
2214
2215void Context::readPixels(GLint x,
2216 GLint y,
2217 GLsizei width,
2218 GLsizei height,
2219 GLenum format,
2220 GLenum type,
2221 GLvoid *pixels)
2222{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002223 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002224
2225 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2226 ASSERT(framebufferObject);
2227
2228 Rectangle area(x, y, width, height);
Jamie Madill437fa652016-05-03 15:13:24 -04002229 handleError(framebufferObject->readPixels(mState, area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002230}
2231
2232void Context::copyTexImage2D(GLenum target,
2233 GLint level,
2234 GLenum internalformat,
2235 GLint x,
2236 GLint y,
2237 GLsizei width,
2238 GLsizei height,
2239 GLint border)
2240{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002241 // Only sync the read FBO
2242 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2243
Jamie Madillc29968b2016-01-20 11:17:23 -05002244 Rectangle sourceArea(x, y, width, height);
2245
2246 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2247 Texture *texture =
2248 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002249 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002250}
2251
2252void Context::copyTexSubImage2D(GLenum target,
2253 GLint level,
2254 GLint xoffset,
2255 GLint yoffset,
2256 GLint x,
2257 GLint y,
2258 GLsizei width,
2259 GLsizei height)
2260{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002261 // Only sync the read FBO
2262 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2263
Jamie Madillc29968b2016-01-20 11:17:23 -05002264 Offset destOffset(xoffset, yoffset, 0);
2265 Rectangle sourceArea(x, y, width, height);
2266
2267 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2268 Texture *texture =
2269 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002270 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002271}
2272
2273void Context::copyTexSubImage3D(GLenum target,
2274 GLint level,
2275 GLint xoffset,
2276 GLint yoffset,
2277 GLint zoffset,
2278 GLint x,
2279 GLint y,
2280 GLsizei width,
2281 GLsizei height)
2282{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002283 // Only sync the read FBO
2284 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2285
Jamie Madillc29968b2016-01-20 11:17:23 -05002286 Offset destOffset(xoffset, yoffset, zoffset);
2287 Rectangle sourceArea(x, y, width, height);
2288
2289 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2290 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002291 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002292}
2293
2294void Context::framebufferTexture2D(GLenum target,
2295 GLenum attachment,
2296 GLenum textarget,
2297 GLuint texture,
2298 GLint level)
2299{
2300 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2301 ASSERT(framebuffer);
2302
2303 if (texture != 0)
2304 {
2305 Texture *textureObj = getTexture(texture);
2306
2307 ImageIndex index = ImageIndex::MakeInvalid();
2308
2309 if (textarget == GL_TEXTURE_2D)
2310 {
2311 index = ImageIndex::Make2D(level);
2312 }
2313 else
2314 {
2315 ASSERT(IsCubeMapTextureTarget(textarget));
2316 index = ImageIndex::MakeCube(textarget, level);
2317 }
2318
2319 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2320 }
2321 else
2322 {
2323 framebuffer->resetAttachment(attachment);
2324 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002325
2326 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002327}
2328
2329void Context::framebufferRenderbuffer(GLenum target,
2330 GLenum attachment,
2331 GLenum renderbuffertarget,
2332 GLuint renderbuffer)
2333{
2334 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2335 ASSERT(framebuffer);
2336
2337 if (renderbuffer != 0)
2338 {
2339 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2340 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2341 renderbufferObject);
2342 }
2343 else
2344 {
2345 framebuffer->resetAttachment(attachment);
2346 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002347
2348 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002349}
2350
2351void Context::framebufferTextureLayer(GLenum target,
2352 GLenum attachment,
2353 GLuint texture,
2354 GLint level,
2355 GLint layer)
2356{
2357 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2358 ASSERT(framebuffer);
2359
2360 if (texture != 0)
2361 {
2362 Texture *textureObject = getTexture(texture);
2363
2364 ImageIndex index = ImageIndex::MakeInvalid();
2365
2366 if (textureObject->getTarget() == GL_TEXTURE_3D)
2367 {
2368 index = ImageIndex::Make3D(level, layer);
2369 }
2370 else
2371 {
2372 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2373 index = ImageIndex::Make2DArray(level, layer);
2374 }
2375
2376 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2377 }
2378 else
2379 {
2380 framebuffer->resetAttachment(attachment);
2381 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002382
2383 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002384}
2385
2386void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2387{
2388 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2389 ASSERT(framebuffer);
2390 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002391 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002392}
2393
2394void Context::readBuffer(GLenum mode)
2395{
2396 Framebuffer *readFBO = mState.getReadFramebuffer();
2397 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002398 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002399}
2400
2401void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2402{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002403 // Only sync the FBO
2404 mState.syncDirtyObject(target);
2405
Jamie Madillc29968b2016-01-20 11:17:23 -05002406 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2407 ASSERT(framebuffer);
2408
2409 // The specification isn't clear what should be done when the framebuffer isn't complete.
2410 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002411 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002412}
2413
2414void Context::invalidateFramebuffer(GLenum target,
2415 GLsizei numAttachments,
2416 const GLenum *attachments)
2417{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002418 // Only sync the FBO
2419 mState.syncDirtyObject(target);
2420
Jamie Madillc29968b2016-01-20 11:17:23 -05002421 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2422 ASSERT(framebuffer);
2423
Jamie Madill437fa652016-05-03 15:13:24 -04002424 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002425 {
Jamie Madill437fa652016-05-03 15:13:24 -04002426 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002427 }
Jamie Madill437fa652016-05-03 15:13:24 -04002428
2429 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002430}
2431
2432void Context::invalidateSubFramebuffer(GLenum target,
2433 GLsizei numAttachments,
2434 const GLenum *attachments,
2435 GLint x,
2436 GLint y,
2437 GLsizei width,
2438 GLsizei height)
2439{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002440 // Only sync the FBO
2441 mState.syncDirtyObject(target);
2442
Jamie Madillc29968b2016-01-20 11:17:23 -05002443 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2444 ASSERT(framebuffer);
2445
Jamie Madill437fa652016-05-03 15:13:24 -04002446 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002447 {
Jamie Madill437fa652016-05-03 15:13:24 -04002448 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002449 }
Jamie Madill437fa652016-05-03 15:13:24 -04002450
2451 Rectangle area(x, y, width, height);
2452 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002453}
2454
Jamie Madill73a84962016-02-12 09:27:23 -05002455void Context::texImage2D(GLenum target,
2456 GLint level,
2457 GLint internalformat,
2458 GLsizei width,
2459 GLsizei height,
2460 GLint border,
2461 GLenum format,
2462 GLenum type,
2463 const GLvoid *pixels)
2464{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002465 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002466
2467 Extents size(width, height, 1);
2468 Texture *texture =
2469 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002470 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2471 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002472}
2473
2474void Context::texImage3D(GLenum target,
2475 GLint level,
2476 GLint internalformat,
2477 GLsizei width,
2478 GLsizei height,
2479 GLsizei depth,
2480 GLint border,
2481 GLenum format,
2482 GLenum type,
2483 const GLvoid *pixels)
2484{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002485 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002486
2487 Extents size(width, height, depth);
2488 Texture *texture = getTargetTexture(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::texSubImage2D(GLenum target,
2494 GLint level,
2495 GLint xoffset,
2496 GLint yoffset,
2497 GLsizei width,
2498 GLsizei height,
2499 GLenum format,
2500 GLenum type,
2501 const GLvoid *pixels)
2502{
2503 // Zero sized uploads are valid but no-ops
2504 if (width == 0 || height == 0)
2505 {
2506 return;
2507 }
2508
Jamie Madillad9f24e2016-02-12 09:27:24 -05002509 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002510
2511 Box area(xoffset, yoffset, 0, width, height, 1);
2512 Texture *texture =
2513 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002514 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2515 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002516}
2517
2518void Context::texSubImage3D(GLenum target,
2519 GLint level,
2520 GLint xoffset,
2521 GLint yoffset,
2522 GLint zoffset,
2523 GLsizei width,
2524 GLsizei height,
2525 GLsizei depth,
2526 GLenum format,
2527 GLenum type,
2528 const GLvoid *pixels)
2529{
2530 // Zero sized uploads are valid but no-ops
2531 if (width == 0 || height == 0 || depth == 0)
2532 {
2533 return;
2534 }
2535
Jamie Madillad9f24e2016-02-12 09:27:24 -05002536 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002537
2538 Box area(xoffset, yoffset, zoffset, width, height, depth);
2539 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002540 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2541 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002542}
2543
2544void Context::compressedTexImage2D(GLenum target,
2545 GLint level,
2546 GLenum internalformat,
2547 GLsizei width,
2548 GLsizei height,
2549 GLint border,
2550 GLsizei imageSize,
2551 const GLvoid *data)
2552{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002553 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002554
2555 Extents size(width, height, 1);
2556 Texture *texture =
2557 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002558 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2559 size, imageSize,
2560 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002561}
2562
2563void Context::compressedTexImage3D(GLenum target,
2564 GLint level,
2565 GLenum internalformat,
2566 GLsizei width,
2567 GLsizei height,
2568 GLsizei depth,
2569 GLint border,
2570 GLsizei imageSize,
2571 const GLvoid *data)
2572{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002573 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002574
2575 Extents size(width, height, depth);
2576 Texture *texture = getTargetTexture(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::compressedTexSubImage2D(GLenum target,
2583 GLint level,
2584 GLint xoffset,
2585 GLint yoffset,
2586 GLsizei width,
2587 GLsizei height,
2588 GLenum format,
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 Box area(xoffset, yoffset, 0, width, height, 1);
2595 Texture *texture =
2596 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002597 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2598 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002599}
2600
2601void Context::compressedTexSubImage3D(GLenum target,
2602 GLint level,
2603 GLint xoffset,
2604 GLint yoffset,
2605 GLint zoffset,
2606 GLsizei width,
2607 GLsizei height,
2608 GLsizei depth,
2609 GLenum format,
2610 GLsizei imageSize,
2611 const GLvoid *data)
2612{
2613 // Zero sized uploads are valid but no-ops
2614 if (width == 0 || height == 0)
2615 {
2616 return;
2617 }
2618
Jamie Madillad9f24e2016-02-12 09:27:24 -05002619 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002620
2621 Box area(xoffset, yoffset, zoffset, width, height, depth);
2622 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002623 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2624 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002625}
2626
Olli Etuaho4f667482016-03-30 15:56:35 +03002627void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2628{
2629 Buffer *buffer = getState().getTargetBuffer(target);
2630 ASSERT(buffer);
2631
2632 if (!buffer->isMapped())
2633 {
2634 *params = nullptr;
2635 }
2636 else
2637 {
2638 *params = buffer->getMapPointer();
2639 }
2640}
2641
2642GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2643{
2644 Buffer *buffer = getState().getTargetBuffer(target);
2645 ASSERT(buffer);
2646
2647 Error error = buffer->map(access);
2648 if (error.isError())
2649 {
Jamie Madill437fa652016-05-03 15:13:24 -04002650 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002651 return nullptr;
2652 }
2653
2654 return buffer->getMapPointer();
2655}
2656
2657GLboolean Context::unmapBuffer(GLenum target)
2658{
2659 Buffer *buffer = getState().getTargetBuffer(target);
2660 ASSERT(buffer);
2661
2662 GLboolean result;
2663 Error error = buffer->unmap(&result);
2664 if (error.isError())
2665 {
Jamie Madill437fa652016-05-03 15:13:24 -04002666 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002667 return GL_FALSE;
2668 }
2669
2670 return result;
2671}
2672
2673GLvoid *Context::mapBufferRange(GLenum target,
2674 GLintptr offset,
2675 GLsizeiptr length,
2676 GLbitfield access)
2677{
2678 Buffer *buffer = getState().getTargetBuffer(target);
2679 ASSERT(buffer);
2680
2681 Error error = buffer->mapRange(offset, length, access);
2682 if (error.isError())
2683 {
Jamie Madill437fa652016-05-03 15:13:24 -04002684 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002685 return nullptr;
2686 }
2687
2688 return buffer->getMapPointer();
2689}
2690
2691void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2692{
2693 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2694}
2695
Jamie Madillad9f24e2016-02-12 09:27:24 -05002696void Context::syncStateForReadPixels()
2697{
2698 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2699}
2700
2701void Context::syncStateForTexImage()
2702{
2703 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2704}
2705
2706void Context::syncStateForClear()
2707{
2708 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2709}
2710
2711void Context::syncStateForBlit()
2712{
2713 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2714}
2715
Jamie Madillc29968b2016-01-20 11:17:23 -05002716} // namespace gl