blob: 25596579e98c63f8c2281fa3985e2b84e1dc5302 [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>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Jamie Madillb9293972015-02-19 11:07:54 -050015
Sami Väisänene45e53b2016-05-25 10:36:04 +030016#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040017#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050018#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050019#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050020#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050021#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050022#include "libANGLE/Fence.h"
23#include "libANGLE/Framebuffer.h"
24#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030025#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050026#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050028#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/ResourceManager.h"
30#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050031#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050032#include "libANGLE/Texture.h"
33#include "libANGLE/TransformFeedback.h"
34#include "libANGLE/VertexArray.h"
35#include "libANGLE/formatutils.h"
36#include "libANGLE/validationES.h"
Jamie Madill437fa652016-05-03 15:13:24 -040037#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040038#include "libANGLE/renderer/EGLImplFactory.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000039
Geoff Langf6db0982015-08-25 13:04:00 -040040namespace
41{
42
Ian Ewell3ffd78b2016-01-22 16:09:42 -050043template <typename T>
44gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
45{
46 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
47 ASSERT(queryObject != nullptr);
48
49 switch (pname)
50 {
51 case GL_QUERY_RESULT_EXT:
52 return queryObject->getResult(params);
53 case GL_QUERY_RESULT_AVAILABLE_EXT:
54 {
55 bool available;
56 gl::Error error = queryObject->isResultAvailable(&available);
57 if (!error.isError())
58 {
59 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
60 }
61 return error;
62 }
63 default:
64 UNREACHABLE();
65 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
66 }
67}
68
Geoff Langf6db0982015-08-25 13:04:00 -040069void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
70{
Geoff Lang1a683462015-09-29 15:09:59 -040071 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040072 {
73 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
74 tfBufferIndex++)
75 {
76 const OffsetBindingPointer<gl::Buffer> &buffer =
77 transformFeedback->getIndexedBuffer(tfBufferIndex);
78 if (buffer.get() != nullptr)
79 {
80 buffer->onTransformFeedback();
81 }
82 }
83 }
84}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050085
86// Attribute map queries.
87EGLint GetClientVersion(const egl::AttributeMap &attribs)
88{
Ian Ewellec2c0c52016-04-05 13:46:26 -040089 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -050090}
91
92GLenum GetResetStrategy(const egl::AttributeMap &attribs)
93{
Ian Ewellec2c0c52016-04-05 13:46:26 -040094 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
95 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -050096 switch (attrib)
97 {
98 case EGL_NO_RESET_NOTIFICATION:
99 return GL_NO_RESET_NOTIFICATION_EXT;
100 case EGL_LOSE_CONTEXT_ON_RESET:
101 return GL_LOSE_CONTEXT_ON_RESET_EXT;
102 default:
103 UNREACHABLE();
104 return GL_NONE;
105 }
106}
107
108bool GetRobustAccess(const egl::AttributeMap &attribs)
109{
110 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
111}
112
113bool GetDebug(const egl::AttributeMap &attribs)
114{
115 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
116}
117
118bool GetNoError(const egl::AttributeMap &attribs)
119{
120 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
121}
122
Geoff Langf6db0982015-08-25 13:04:00 -0400123} // anonymous namespace
124
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000125namespace gl
126{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000127
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400128Context::Context(rx::EGLImplFactory *implFactory,
129 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400130 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500131 const egl::AttributeMap &attribs)
132 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700133 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500134 mCaps,
135 mTextureCaps,
136 mExtensions,
137 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mLimitations,
139 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700140 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500141 mCompiler(nullptr),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400143 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144 mClientType(EGL_OPENGL_ES_API),
145 mHasBeenCurrent(false),
146 mContextLost(false),
147 mResetStatus(GL_NO_ERROR),
148 mResetStrategy(GetResetStrategy(attribs)),
149 mRobustAccess(GetRobustAccess(attribs)),
150 mCurrentSurface(nullptr),
151 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000152{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000154
Jamie Madill00ed7a12016-05-19 13:13:38 -0400155 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400156
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700157 mGLState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100158
Shannon Woods53a94a82014-06-24 15:20:36 -0400159 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400160
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400161 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000162 {
163 mResourceManager = shareContext->mResourceManager;
164 mResourceManager->addRef();
165 }
166 else
167 {
Jamie Madill901b3792016-05-26 09:20:40 -0400168 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000169 }
170
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700171 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400172
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000173 // [OpenGL ES 2.0.24] section 3.7 page 83:
174 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
175 // and cube map texture state vectors respectively associated with them.
176 // In order that access to these initial textures not be lost, they are treated as texture
177 // objects all of whose names are 0.
178
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400179 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500180 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500181
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400182 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500183 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400184
185 if (mClientVersion >= 3)
186 {
187 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400188 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500189 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400190
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400191 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500192 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400193 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000194
Ian Ewellbda75592016-04-18 17:25:54 -0400195 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
196 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400197 Texture *zeroTextureExternal =
198 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400199 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
200 }
201
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700202 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500203
Jamie Madill57a89722013-07-02 11:57:03 -0400204 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205 bindArrayBuffer(0);
206 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400207
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000208 bindRenderbuffer(0);
209
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000210 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400211 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000212 {
213 bindIndexedUniformBuffer(0, i, 0, -1);
214 }
215
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000216 bindCopyReadBuffer(0);
217 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000218 bindPixelPackBuffer(0);
219 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000220
Geoff Lang1a683462015-09-29 15:09:59 -0400221 if (mClientVersion >= 3)
222 {
223 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
224 // In the initial state, a default transform feedback object is bound and treated as
225 // a transform feedback object with a name of zero. That object is bound any time
226 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400227 bindTransformFeedback(0);
228 }
Geoff Langc8058452014-02-03 12:04:11 -0500229
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700230 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500231
232 // Initialize dirty bit masks
233 // TODO(jmadill): additional ES3 state
234 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
235 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
236 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
237 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
238 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
239 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400240 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500241 // No dirty objects.
242
243 // Readpixels uses the pack state and read FBO
244 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
245 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
246 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
247 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
248 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400249 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500250 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
251
252 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
253 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
254 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
255 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
256 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
257 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
258 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
259 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
260 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
261 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
262 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
263 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
264
265 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
266 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
267 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
268 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400269
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400270 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000271}
272
273Context::~Context()
274{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700275 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000276
Corentin Wallez37c39792015-08-20 14:19:46 -0400277 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400279 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400280 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400281 {
282 SafeDelete(framebuffer.second);
283 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 }
285
Corentin Wallez80b24112015-08-25 16:41:57 -0400286 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000287 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400288 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 }
290
Corentin Wallez80b24112015-08-25 16:41:57 -0400291 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000292 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400293 if (query.second != nullptr)
294 {
295 query.second->release();
296 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 }
298
Corentin Wallez80b24112015-08-25 16:41:57 -0400299 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400300 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400301 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400302 }
303
Corentin Wallez80b24112015-08-25 16:41:57 -0400304 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500305 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500306 if (transformFeedback.second != nullptr)
307 {
308 transformFeedback.second->release();
309 }
Geoff Langc8058452014-02-03 12:04:11 -0500310 }
311
Jamie Madilldedd7b92014-11-05 16:30:36 -0500312 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400313 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500314 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400315 }
316 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000317
Corentin Wallez51706ea2015-08-07 14:39:22 -0400318 if (mCurrentSurface != nullptr)
319 {
320 releaseSurface();
321 }
322
Jamie Madill1e9ae072014-11-06 15:27:21 -0500323 if (mResourceManager)
324 {
325 mResourceManager->release();
326 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500327
328 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329}
330
daniel@transgaming.comad629872012-11-28 19:32:06 +0000331void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332{
Jamie Madill77a72f62015-04-14 11:18:32 -0400333 ASSERT(surface != nullptr);
334
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000335 if (!mHasBeenCurrent)
336 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000337 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400338 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000339
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700340 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
341 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000342
343 mHasBeenCurrent = true;
344 }
345
Jamie Madill1b94d432015-08-07 13:23:23 -0400346 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700347 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400348
Corentin Wallez51706ea2015-08-07 14:39:22 -0400349 if (mCurrentSurface)
350 {
351 releaseSurface();
352 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000353 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400354 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000355
Corentin Wallez37c39792015-08-20 14:19:46 -0400356 // Update default framebuffer, the binding of the previous default
357 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400358 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400359 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700360 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400361 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700362 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400363 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700364 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400365 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700366 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400367 }
368 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400369 }
Ian Ewell292f0052016-02-04 10:37:32 -0500370
371 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700372 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000373}
374
Jamie Madill77a72f62015-04-14 11:18:32 -0400375void Context::releaseSurface()
376{
Corentin Wallez37c39792015-08-20 14:19:46 -0400377 ASSERT(mCurrentSurface != nullptr);
378
379 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400380 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400381 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700382 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400383 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700384 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400385 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700386 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400387 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700388 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400389 }
390 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400391 }
392
Corentin Wallez51706ea2015-08-07 14:39:22 -0400393 mCurrentSurface->setIsCurrent(false);
394 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400395}
396
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000397// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398void Context::markContextLost()
399{
400 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
401 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
402 mContextLost = true;
403}
404
405bool Context::isContextLost()
406{
407 return mContextLost;
408}
409
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410GLuint Context::createBuffer()
411{
412 return mResourceManager->createBuffer();
413}
414
415GLuint Context::createProgram()
416{
Jamie Madill901b3792016-05-26 09:20:40 -0400417 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418}
419
420GLuint Context::createShader(GLenum type)
421{
Jamie Madill901b3792016-05-26 09:20:40 -0400422 return mResourceManager->createShader(mImplementation.get(),
423 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424}
425
426GLuint Context::createTexture()
427{
428 return mResourceManager->createTexture();
429}
430
431GLuint Context::createRenderbuffer()
432{
433 return mResourceManager->createRenderbuffer();
434}
435
Geoff Lang882033e2014-09-30 11:26:07 -0400436GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400437{
Jamie Madill901b3792016-05-26 09:20:40 -0400438 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400439
Cooper Partind8e62a32015-01-29 15:21:25 -0800440 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400441}
442
Sami Väisänene45e53b2016-05-25 10:36:04 +0300443GLuint Context::createPaths(GLsizei range)
444{
445 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
446 if (resultOrError.isError())
447 {
448 handleError(resultOrError.getError());
449 return 0;
450 }
451 return resultOrError.getResult();
452}
453
Jamie Madill57a89722013-07-02 11:57:03 -0400454GLuint Context::createVertexArray()
455{
Geoff Lang36167ab2015-12-07 10:27:14 -0500456 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
457 mVertexArrayMap[vertexArray] = nullptr;
458 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400459}
460
Jamie Madilldc356042013-07-19 16:36:57 -0400461GLuint Context::createSampler()
462{
463 return mResourceManager->createSampler();
464}
465
Geoff Langc8058452014-02-03 12:04:11 -0500466GLuint Context::createTransformFeedback()
467{
Geoff Lang36167ab2015-12-07 10:27:14 -0500468 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
469 mTransformFeedbackMap[transformFeedback] = nullptr;
470 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500471}
472
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473// Returns an unused framebuffer name
474GLuint Context::createFramebuffer()
475{
476 GLuint handle = mFramebufferHandleAllocator.allocate();
477
478 mFramebufferMap[handle] = NULL;
479
480 return handle;
481}
482
Jamie Madill33dc8432013-07-26 11:55:05 -0400483GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000484{
Jamie Madill33dc8432013-07-26 11:55:05 -0400485 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000486
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400487 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488
489 return handle;
490}
491
492// Returns an unused query name
493GLuint Context::createQuery()
494{
495 GLuint handle = mQueryHandleAllocator.allocate();
496
497 mQueryMap[handle] = NULL;
498
499 return handle;
500}
501
502void Context::deleteBuffer(GLuint buffer)
503{
504 if (mResourceManager->getBuffer(buffer))
505 {
506 detachBuffer(buffer);
507 }
Jamie Madill893ab082014-05-16 16:56:10 -0400508
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000509 mResourceManager->deleteBuffer(buffer);
510}
511
512void Context::deleteShader(GLuint shader)
513{
514 mResourceManager->deleteShader(shader);
515}
516
517void Context::deleteProgram(GLuint program)
518{
519 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000520}
521
522void Context::deleteTexture(GLuint texture)
523{
524 if (mResourceManager->getTexture(texture))
525 {
526 detachTexture(texture);
527 }
528
529 mResourceManager->deleteTexture(texture);
530}
531
532void Context::deleteRenderbuffer(GLuint renderbuffer)
533{
534 if (mResourceManager->getRenderbuffer(renderbuffer))
535 {
536 detachRenderbuffer(renderbuffer);
537 }
Jamie Madill893ab082014-05-16 16:56:10 -0400538
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000539 mResourceManager->deleteRenderbuffer(renderbuffer);
540}
541
Jamie Madillcd055f82013-07-26 11:55:15 -0400542void Context::deleteFenceSync(GLsync fenceSync)
543{
544 // The spec specifies the underlying Fence object is not deleted until all current
545 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
546 // and since our API is currently designed for being called from a single thread, we can delete
547 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700548 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400549}
550
Sami Väisänene45e53b2016-05-25 10:36:04 +0300551void Context::deletePaths(GLuint first, GLsizei range)
552{
553 mResourceManager->deletePaths(first, range);
554}
555
556bool Context::hasPathData(GLuint path) const
557{
558 const auto *pathObj = mResourceManager->getPath(path);
559 if (pathObj == nullptr)
560 return false;
561
562 return pathObj->hasPathData();
563}
564
565bool Context::hasPath(GLuint path) const
566{
567 return mResourceManager->hasPath(path);
568}
569
570void Context::setPathCommands(GLuint path,
571 GLsizei numCommands,
572 const GLubyte *commands,
573 GLsizei numCoords,
574 GLenum coordType,
575 const void *coords)
576{
577 auto *pathObject = mResourceManager->getPath(path);
578
579 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
580}
581
582void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
583{
584 auto *pathObj = mResourceManager->getPath(path);
585
586 switch (pname)
587 {
588 case GL_PATH_STROKE_WIDTH_CHROMIUM:
589 pathObj->setStrokeWidth(value);
590 break;
591 case GL_PATH_END_CAPS_CHROMIUM:
592 pathObj->setEndCaps(static_cast<GLenum>(value));
593 break;
594 case GL_PATH_JOIN_STYLE_CHROMIUM:
595 pathObj->setJoinStyle(static_cast<GLenum>(value));
596 break;
597 case GL_PATH_MITER_LIMIT_CHROMIUM:
598 pathObj->setMiterLimit(value);
599 break;
600 case GL_PATH_STROKE_BOUND_CHROMIUM:
601 pathObj->setStrokeBound(value);
602 break;
603 default:
604 UNREACHABLE();
605 break;
606 }
607}
608
609void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
610{
611 const auto *pathObj = mResourceManager->getPath(path);
612
613 switch (pname)
614 {
615 case GL_PATH_STROKE_WIDTH_CHROMIUM:
616 *value = pathObj->getStrokeWidth();
617 break;
618 case GL_PATH_END_CAPS_CHROMIUM:
619 *value = static_cast<GLfloat>(pathObj->getEndCaps());
620 break;
621 case GL_PATH_JOIN_STYLE_CHROMIUM:
622 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
623 break;
624 case GL_PATH_MITER_LIMIT_CHROMIUM:
625 *value = pathObj->getMiterLimit();
626 break;
627 case GL_PATH_STROKE_BOUND_CHROMIUM:
628 *value = pathObj->getStrokeBound();
629 break;
630 default:
631 UNREACHABLE();
632 break;
633 }
634}
635
636void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
637{
638 mGLState.setPathStencilFunc(func, ref, mask);
639}
640
Jamie Madill57a89722013-07-02 11:57:03 -0400641void Context::deleteVertexArray(GLuint vertexArray)
642{
Geoff Lang36167ab2015-12-07 10:27:14 -0500643 auto iter = mVertexArrayMap.find(vertexArray);
644 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000645 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500646 VertexArray *vertexArrayObject = iter->second;
647 if (vertexArrayObject != nullptr)
648 {
649 detachVertexArray(vertexArray);
650 delete vertexArrayObject;
651 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000652
Geoff Lang36167ab2015-12-07 10:27:14 -0500653 mVertexArrayMap.erase(iter);
654 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400655 }
656}
657
Jamie Madilldc356042013-07-19 16:36:57 -0400658void Context::deleteSampler(GLuint sampler)
659{
660 if (mResourceManager->getSampler(sampler))
661 {
662 detachSampler(sampler);
663 }
664
665 mResourceManager->deleteSampler(sampler);
666}
667
Geoff Langc8058452014-02-03 12:04:11 -0500668void Context::deleteTransformFeedback(GLuint transformFeedback)
669{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500670 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500671 if (iter != mTransformFeedbackMap.end())
672 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500673 TransformFeedback *transformFeedbackObject = iter->second;
674 if (transformFeedbackObject != nullptr)
675 {
676 detachTransformFeedback(transformFeedback);
677 transformFeedbackObject->release();
678 }
679
Geoff Lang50b3fe82015-12-08 14:49:12 +0000680 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500681 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500682 }
683}
684
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000685void Context::deleteFramebuffer(GLuint framebuffer)
686{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500687 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000688
689 if (framebufferObject != mFramebufferMap.end())
690 {
691 detachFramebuffer(framebuffer);
692
693 mFramebufferHandleAllocator.release(framebufferObject->first);
694 delete framebufferObject->second;
695 mFramebufferMap.erase(framebufferObject);
696 }
697}
698
Jamie Madill33dc8432013-07-26 11:55:05 -0400699void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000700{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500701 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000702
Jamie Madill33dc8432013-07-26 11:55:05 -0400703 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000704 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400705 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000706 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400707 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708 }
709}
710
711void Context::deleteQuery(GLuint query)
712{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500713 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714 if (queryObject != mQueryMap.end())
715 {
716 mQueryHandleAllocator.release(queryObject->first);
717 if (queryObject->second)
718 {
719 queryObject->second->release();
720 }
721 mQueryMap.erase(queryObject);
722 }
723}
724
Geoff Lang70d0f492015-12-10 17:45:46 -0500725Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000726{
727 return mResourceManager->getBuffer(handle);
728}
729
Geoff Lang48dcae72014-02-05 16:28:24 -0500730Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000731{
732 return mResourceManager->getShader(handle);
733}
734
Geoff Lang48dcae72014-02-05 16:28:24 -0500735Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000736{
737 return mResourceManager->getProgram(handle);
738}
739
Jamie Madill570f7c82014-07-03 10:38:54 -0400740Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000741{
742 return mResourceManager->getTexture(handle);
743}
744
Geoff Lang70d0f492015-12-10 17:45:46 -0500745Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000746{
747 return mResourceManager->getRenderbuffer(handle);
748}
749
Jamie Madillcd055f82013-07-26 11:55:15 -0400750FenceSync *Context::getFenceSync(GLsync handle) const
751{
Minmin Gong794e0002015-04-07 18:31:54 -0700752 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400753}
754
Jamie Madill57a89722013-07-02 11:57:03 -0400755VertexArray *Context::getVertexArray(GLuint handle) const
756{
757 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500758 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400759}
760
Jamie Madilldc356042013-07-19 16:36:57 -0400761Sampler *Context::getSampler(GLuint handle) const
762{
763 return mResourceManager->getSampler(handle);
764}
765
Geoff Langc8058452014-02-03 12:04:11 -0500766TransformFeedback *Context::getTransformFeedback(GLuint handle) const
767{
Geoff Lang36167ab2015-12-07 10:27:14 -0500768 auto iter = mTransformFeedbackMap.find(handle);
769 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500770}
771
Geoff Lang70d0f492015-12-10 17:45:46 -0500772LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
773{
774 switch (identifier)
775 {
776 case GL_BUFFER:
777 return getBuffer(name);
778 case GL_SHADER:
779 return getShader(name);
780 case GL_PROGRAM:
781 return getProgram(name);
782 case GL_VERTEX_ARRAY:
783 return getVertexArray(name);
784 case GL_QUERY:
785 return getQuery(name);
786 case GL_TRANSFORM_FEEDBACK:
787 return getTransformFeedback(name);
788 case GL_SAMPLER:
789 return getSampler(name);
790 case GL_TEXTURE:
791 return getTexture(name);
792 case GL_RENDERBUFFER:
793 return getRenderbuffer(name);
794 case GL_FRAMEBUFFER:
795 return getFramebuffer(name);
796 default:
797 UNREACHABLE();
798 return nullptr;
799 }
800}
801
802LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
803{
804 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
805}
806
Jamie Madilldc356042013-07-19 16:36:57 -0400807bool Context::isSampler(GLuint samplerName) const
808{
809 return mResourceManager->isSampler(samplerName);
810}
811
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500812void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813{
Jamie Madill901b3792016-05-26 09:20:40 -0400814 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700815 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816}
817
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500818void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000819{
Jamie Madill901b3792016-05-26 09:20:40 -0400820 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700821 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822}
823
Jamie Madilldedd7b92014-11-05 16:30:36 -0500824void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500826 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827
Jamie Madilldedd7b92014-11-05 16:30:36 -0500828 if (handle == 0)
829 {
830 texture = mZeroTextures[target].get();
831 }
832 else
833 {
Jamie Madill901b3792016-05-26 09:20:40 -0400834 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500835 }
836
837 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700838 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000839}
840
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500841void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000842{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500843 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700844 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000845}
846
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500847void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000848{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500849 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700850 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000851}
852
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500853void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854{
Jamie Madill901b3792016-05-26 09:20:40 -0400855 Renderbuffer *renderbuffer =
856 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700857 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000858}
859
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500860void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400861{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500862 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700863 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400864}
865
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500866void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400867{
Geoff Lang76b10c92014-09-05 16:28:14 -0400868 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400869 Sampler *sampler =
870 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700871 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400872}
873
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500874void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000875{
Jamie Madill901b3792016-05-26 09:20:40 -0400876 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700877 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000878}
879
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500880void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
881 GLuint index,
882 GLintptr offset,
883 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000884{
Jamie Madill901b3792016-05-26 09:20:40 -0400885 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700886 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000887}
888
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500889void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000890{
Jamie Madill901b3792016-05-26 09:20:40 -0400891 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700892 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000893}
894
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500895void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
896 GLuint index,
897 GLintptr offset,
898 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000899{
Jamie Madill901b3792016-05-26 09:20:40 -0400900 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700901 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000902}
903
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500904void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000905{
Jamie Madill901b3792016-05-26 09:20:40 -0400906 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700907 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000908}
909
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500910void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000911{
Jamie Madill901b3792016-05-26 09:20:40 -0400912 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700913 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000914}
915
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500916void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000917{
Jamie Madill901b3792016-05-26 09:20:40 -0400918 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700919 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000920}
921
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500922void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000923{
Jamie Madill901b3792016-05-26 09:20:40 -0400924 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700925 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000926}
927
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000928void Context::useProgram(GLuint program)
929{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700930 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000931}
932
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500933void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500934{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500935 TransformFeedback *transformFeedback =
936 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700937 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500938}
939
Geoff Lang5aad9672014-09-08 11:10:42 -0400940Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400943 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000944
Geoff Lang5aad9672014-09-08 11:10:42 -0400945 // begin query
946 Error error = queryObject->begin();
947 if (error.isError())
948 {
949 return error;
950 }
951
952 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700953 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954
Geoff Lang5aad9672014-09-08 11:10:42 -0400955 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956}
957
Geoff Lang5aad9672014-09-08 11:10:42 -0400958Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700960 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400961 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962
Geoff Lang5aad9672014-09-08 11:10:42 -0400963 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000964
Geoff Lang5aad9672014-09-08 11:10:42 -0400965 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700966 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400967
968 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969}
970
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500971Error Context::queryCounter(GLuint id, GLenum target)
972{
973 ASSERT(target == GL_TIMESTAMP_EXT);
974
975 Query *queryObject = getQuery(id, true, target);
976 ASSERT(queryObject);
977
978 return queryObject->queryCounter();
979}
980
981void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
982{
983 switch (pname)
984 {
985 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500987 break;
988 case GL_QUERY_COUNTER_BITS_EXT:
989 switch (target)
990 {
991 case GL_TIME_ELAPSED_EXT:
992 params[0] = getExtensions().queryCounterBitsTimeElapsed;
993 break;
994 case GL_TIMESTAMP_EXT:
995 params[0] = getExtensions().queryCounterBitsTimestamp;
996 break;
997 default:
998 UNREACHABLE();
999 params[0] = 0;
1000 break;
1001 }
1002 break;
1003 default:
1004 UNREACHABLE();
1005 return;
1006 }
1007}
1008
1009Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1010{
1011 return GetQueryObjectParameter(this, id, pname, params);
1012}
1013
1014Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1015{
1016 return GetQueryObjectParameter(this, id, pname, params);
1017}
1018
1019Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1020{
1021 return GetQueryObjectParameter(this, id, pname, params);
1022}
1023
1024Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1025{
1026 return GetQueryObjectParameter(this, id, pname, params);
1027}
1028
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001029Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001031 auto framebufferIt = mFramebufferMap.find(handle);
1032 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001033}
1034
Jamie Madill33dc8432013-07-26 11:55:05 -04001035FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001036{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001037 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001038
Jamie Madill33dc8432013-07-26 11:55:05 -04001039 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040 {
1041 return NULL;
1042 }
1043 else
1044 {
1045 return fence->second;
1046 }
1047}
1048
1049Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1050{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001051 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001052
1053 if (query == mQueryMap.end())
1054 {
1055 return NULL;
1056 }
1057 else
1058 {
1059 if (!query->second && create)
1060 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001061 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001062 query->second->addRef();
1063 }
1064 return query->second;
1065 }
1066}
1067
Geoff Lang70d0f492015-12-10 17:45:46 -05001068Query *Context::getQuery(GLuint handle) const
1069{
1070 auto iter = mQueryMap.find(handle);
1071 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1072}
1073
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001074Texture *Context::getTargetTexture(GLenum target) const
1075{
Ian Ewellbda75592016-04-18 17:25:54 -04001076 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001077 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001078}
1079
Geoff Lang76b10c92014-09-05 16:28:14 -04001080Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083}
1084
Geoff Lang492a7e42014-11-05 13:27:06 -05001085Compiler *Context::getCompiler() const
1086{
1087 return mCompiler;
1088}
1089
Jamie Madill893ab082014-05-16 16:56:10 -04001090void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091{
1092 switch (pname)
1093 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001094 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001095 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001096 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001097 mGLState.getBooleanv(pname, params);
1098 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001099 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100}
1101
Jamie Madill893ab082014-05-16 16:56:10 -04001102void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001103{
Shannon Woods53a94a82014-06-24 15:20:36 -04001104 // Queries about context capabilities and maximums are answered by Context.
1105 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106 switch (pname)
1107 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001108 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001109 params[0] = mCaps.minAliasedLineWidth;
1110 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001111 break;
1112 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001113 params[0] = mCaps.minAliasedPointSize;
1114 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001116 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001117 ASSERT(mExtensions.textureFilterAnisotropic);
1118 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001119 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001120 case GL_MAX_TEXTURE_LOD_BIAS:
1121 *params = mCaps.maxLODBias;
1122 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001123
1124 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1125 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1126 {
1127 ASSERT(mExtensions.pathRendering);
1128 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1129 memcpy(params, m, 16 * sizeof(GLfloat));
1130 }
1131 break;
1132
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001133 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001134 mGLState.getFloatv(pname, params);
1135 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001136 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001137}
1138
Jamie Madill893ab082014-05-16 16:56:10 -04001139void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001140{
Shannon Woods53a94a82014-06-24 15:20:36 -04001141 // Queries about context capabilities and maximums are answered by Context.
1142 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001143
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001144 switch (pname)
1145 {
Geoff Lang301d1612014-07-09 10:34:37 -04001146 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1147 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1148 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001149 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1150 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1151 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001152 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1153 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1154 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001155 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001156 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1157 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1158 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001159 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001160 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001161 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1162 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1163 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1164 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001165 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1166 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001167 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1168 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001169 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001170 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1171 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1172 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1173 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001174 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1175 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001176 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1177 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001178 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1179 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1180 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001181 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1182 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1183 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001184 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 case GL_MAX_VIEWPORT_DIMS:
1186 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001187 params[0] = mCaps.maxViewportWidth;
1188 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 }
1190 break;
1191 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001192 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001194 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1195 *params = mResetStrategy;
1196 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001197 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001198 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001199 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001200 case GL_SHADER_BINARY_FORMATS:
1201 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1202 break;
1203 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001204 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001205 break;
1206 case GL_PROGRAM_BINARY_FORMATS:
1207 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001208 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001209 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001210 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001211 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001212
1213 // GL_KHR_debug
1214 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1215 *params = mExtensions.maxDebugMessageLength;
1216 break;
1217 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1218 *params = mExtensions.maxDebugLoggedMessages;
1219 break;
1220 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1221 *params = mExtensions.maxDebugGroupStackDepth;
1222 break;
1223 case GL_MAX_LABEL_LENGTH:
1224 *params = mExtensions.maxLabelLength;
1225 break;
1226
Ian Ewell53f59f42016-01-28 17:36:55 -05001227 // GL_EXT_disjoint_timer_query
1228 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001229 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001230 break;
1231
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001233 mGLState.getIntegerv(mState, pname, params);
1234 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236}
1237
Jamie Madill893ab082014-05-16 16:56:10 -04001238void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001239{
Shannon Woods53a94a82014-06-24 15:20:36 -04001240 // Queries about context capabilities and maximums are answered by Context.
1241 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001242 switch (pname)
1243 {
1244 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001245 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001246 break;
1247 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001248 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001249 break;
1250 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001251 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001252 break;
1253 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001254 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001255 break;
1256 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001257 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001258 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001259
1260 // GL_EXT_disjoint_timer_query
1261 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001262 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001263 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001264 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001265 UNREACHABLE();
1266 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001267 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001268}
1269
Geoff Lang70d0f492015-12-10 17:45:46 -05001270void Context::getPointerv(GLenum pname, void **params) const
1271{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001272 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001273}
1274
Shannon Woods1b2fb852013-08-19 14:28:48 -04001275bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1276{
Shannon Woods53a94a82014-06-24 15:20:36 -04001277 // Queries about context capabilities and maximums are answered by Context.
1278 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001279 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001280 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001281 return mGLState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001282}
1283
1284bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1285{
Shannon Woods53a94a82014-06-24 15:20:36 -04001286 // Queries about context capabilities and maximums are answered by Context.
1287 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001288 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001289 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001290 return mGLState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001291}
1292
Geoff Langf6db0982015-08-25 13:04:00 -04001293Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001294{
Jamie Madill1b94d432015-08-07 13:23:23 -04001295 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001296 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001297 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001298
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001299 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300}
1301
Geoff Langf6db0982015-08-25 13:04:00 -04001302Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1303{
1304 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001305 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001306 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001307
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001308 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001309}
1310
1311Error Context::drawElements(GLenum mode,
1312 GLsizei count,
1313 GLenum type,
1314 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001315 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316{
Jamie Madill1b94d432015-08-07 13:23:23 -04001317 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001318 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001319}
1320
1321Error Context::drawElementsInstanced(GLenum mode,
1322 GLsizei count,
1323 GLenum type,
1324 const GLvoid *indices,
1325 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001326 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001327{
1328 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001329 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1330 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001331}
1332
1333Error Context::drawRangeElements(GLenum mode,
1334 GLuint start,
1335 GLuint end,
1336 GLsizei count,
1337 GLenum type,
1338 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001339 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001340{
1341 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001342 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001343}
1344
Geoff Lang129753a2015-01-09 16:52:09 -05001345Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001346{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001347 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001348}
1349
1350Error Context::finish()
1351{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001352 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353}
1354
Austin Kinross6ee1e782015-05-29 17:05:37 -07001355void Context::insertEventMarker(GLsizei length, const char *marker)
1356{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001357 ASSERT(mImplementation);
1358 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001359}
1360
1361void Context::pushGroupMarker(GLsizei length, const char *marker)
1362{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001363 ASSERT(mImplementation);
1364 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001365}
1366
1367void Context::popGroupMarker()
1368{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001369 ASSERT(mImplementation);
1370 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001371}
1372
Geoff Langd8605522016-04-13 10:19:12 -04001373void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1374{
1375 Program *programObject = getProgram(program);
1376 ASSERT(programObject);
1377
1378 programObject->bindUniformLocation(location, name);
1379}
1380
Sami Väisänena797e062016-05-12 15:23:40 +03001381void Context::setCoverageModulation(GLenum components)
1382{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001383 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001384}
1385
Sami Väisänene45e53b2016-05-25 10:36:04 +03001386void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1387{
1388 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1389}
1390
1391void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1392{
1393 GLfloat I[16];
1394 angle::Matrix<GLfloat>::setToIdentity(I);
1395
1396 mGLState.loadPathRenderingMatrix(matrixMode, I);
1397}
1398
1399void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1400{
1401 const auto *pathObj = mResourceManager->getPath(path);
1402 if (!pathObj)
1403 return;
1404
1405 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1406 syncRendererState();
1407
1408 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1409}
1410
1411void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1412{
1413 const auto *pathObj = mResourceManager->getPath(path);
1414 if (!pathObj)
1415 return;
1416
1417 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1418 syncRendererState();
1419
1420 mImplementation->stencilStrokePath(pathObj, reference, mask);
1421}
1422
1423void Context::coverFillPath(GLuint path, GLenum coverMode)
1424{
1425 const auto *pathObj = mResourceManager->getPath(path);
1426 if (!pathObj)
1427 return;
1428
1429 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1430 syncRendererState();
1431
1432 mImplementation->coverFillPath(pathObj, coverMode);
1433}
1434
1435void Context::coverStrokePath(GLuint path, GLenum coverMode)
1436{
1437 const auto *pathObj = mResourceManager->getPath(path);
1438 if (!pathObj)
1439 return;
1440
1441 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1442 syncRendererState();
1443
1444 mImplementation->coverStrokePath(pathObj, coverMode);
1445}
1446
1447void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1448{
1449 const auto *pathObj = mResourceManager->getPath(path);
1450 if (!pathObj)
1451 return;
1452
1453 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1454 syncRendererState();
1455
1456 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1457}
1458
1459void Context::stencilThenCoverStrokePath(GLuint path,
1460 GLint reference,
1461 GLuint mask,
1462 GLenum coverMode)
1463{
1464 const auto *pathObj = mResourceManager->getPath(path);
1465 if (!pathObj)
1466 return;
1467
1468 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1469 syncRendererState();
1470
1471 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1472}
1473
Jamie Madill437fa652016-05-03 15:13:24 -04001474void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001475{
Geoff Langda5777c2014-07-11 09:52:58 -04001476 if (error.isError())
1477 {
1478 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001479
1480 if (!error.getMessage().empty())
1481 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001482 auto *debug = &mGLState.getDebug();
1483 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1484 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001485 }
Geoff Langda5777c2014-07-11 09:52:58 -04001486 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487}
1488
1489// Get one of the recorded errors and clear its flag, if any.
1490// [OpenGL ES 2.0.24] section 2.5 page 13.
1491GLenum Context::getError()
1492{
Geoff Langda5777c2014-07-11 09:52:58 -04001493 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001494 {
Geoff Langda5777c2014-07-11 09:52:58 -04001495 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001496 }
Geoff Langda5777c2014-07-11 09:52:58 -04001497 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001498 {
Geoff Langda5777c2014-07-11 09:52:58 -04001499 GLenum error = *mErrors.begin();
1500 mErrors.erase(mErrors.begin());
1501 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001502 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001503}
1504
1505GLenum Context::getResetStatus()
1506{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001507 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001508 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001509 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001510 // mResetStatus will be set by the markContextLost callback
1511 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001512 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001513 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001514 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001515 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001516 }
1517
1518 GLenum status = mResetStatus;
1519
1520 if (mResetStatus != GL_NO_ERROR)
1521 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001522 ASSERT(mContextLost);
1523
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001524 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001525 {
1526 mResetStatus = GL_NO_ERROR;
1527 }
1528 }
Jamie Madill893ab082014-05-16 16:56:10 -04001529
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001530 return status;
1531}
1532
1533bool Context::isResetNotificationEnabled()
1534{
1535 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1536}
1537
Corentin Walleze3b10e82015-05-20 11:06:25 -04001538const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001539{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001540 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001541}
1542
1543EGLenum Context::getClientType() const
1544{
1545 return mClientType;
1546}
1547
1548EGLenum Context::getRenderBuffer() const
1549{
Corentin Wallez37c39792015-08-20 14:19:46 -04001550 auto framebufferIt = mFramebufferMap.find(0);
1551 if (framebufferIt != mFramebufferMap.end())
1552 {
1553 const Framebuffer *framebuffer = framebufferIt->second;
1554 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1555
1556 ASSERT(backAttachment != nullptr);
1557 return backAttachment->getSurface()->getRenderBuffer();
1558 }
1559 else
1560 {
1561 return EGL_NONE;
1562 }
Régis Fénéon83107972015-02-05 12:57:44 +01001563}
1564
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001565VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001566{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001567 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001568 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1569 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001570 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001571 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1572
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001573 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001574 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001575
1576 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001577}
1578
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001579TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001580{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001581 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001582 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1583 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001584 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001585 transformFeedback =
1586 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001587 transformFeedback->addRef();
1588 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001589 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001590
1591 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001592}
1593
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001594Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1595{
1596 // Can be called from Bind without a prior call to Gen.
1597 auto framebufferIt = mFramebufferMap.find(framebuffer);
1598 bool neverCreated = framebufferIt == mFramebufferMap.end();
1599 if (neverCreated || framebufferIt->second == nullptr)
1600 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001601 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001602 if (neverCreated)
1603 {
1604 mFramebufferHandleAllocator.reserve(framebuffer);
1605 mFramebufferMap[framebuffer] = newFBO;
1606 return newFBO;
1607 }
1608
1609 framebufferIt->second = newFBO;
1610 }
1611
1612 return framebufferIt->second;
1613}
1614
Geoff Lang36167ab2015-12-07 10:27:14 -05001615bool Context::isVertexArrayGenerated(GLuint vertexArray)
1616{
1617 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1618}
1619
1620bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1621{
1622 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1623}
1624
Shannon Woods53a94a82014-06-24 15:20:36 -04001625void Context::detachTexture(GLuint texture)
1626{
1627 // Simple pass-through to State's detachTexture method, as textures do not require
1628 // allocation map management either here or in the resource manager at detach time.
1629 // Zero textures are held by the Context, and we don't attempt to request them from
1630 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001631 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001632}
1633
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001634void Context::detachBuffer(GLuint buffer)
1635{
Yuly Novikov5807a532015-12-03 13:01:22 -05001636 // Simple pass-through to State's detachBuffer method, since
1637 // only buffer attachments to container objects that are bound to the current context
1638 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001639
Yuly Novikov5807a532015-12-03 13:01:22 -05001640 // [OpenGL ES 3.2] section 5.1.2 page 45:
1641 // Attachments to unbound container objects, such as
1642 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1643 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001644 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001645}
1646
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001647void Context::detachFramebuffer(GLuint framebuffer)
1648{
Shannon Woods53a94a82014-06-24 15:20:36 -04001649 // Framebuffer detachment is handled by Context, because 0 is a valid
1650 // Framebuffer object, and a pointer to it must be passed from Context
1651 // to State at binding time.
1652
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001653 // [OpenGL ES 2.0.24] section 4.4 page 107:
1654 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1655 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1656
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001657 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001658 {
1659 bindReadFramebuffer(0);
1660 }
1661
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001662 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001663 {
1664 bindDrawFramebuffer(0);
1665 }
1666}
1667
1668void Context::detachRenderbuffer(GLuint renderbuffer)
1669{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001670 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
Jamie Madill57a89722013-07-02 11:57:03 -04001673void Context::detachVertexArray(GLuint vertexArray)
1674{
Jamie Madill77a72f62015-04-14 11:18:32 -04001675 // Vertex array detachment is handled by Context, because 0 is a valid
1676 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001677 // binding time.
1678
Jamie Madill57a89722013-07-02 11:57:03 -04001679 // [OpenGL ES 3.0.2] section 2.10 page 43:
1680 // If a vertex array object that is currently bound is deleted, the binding
1681 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001682 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001683 {
1684 bindVertexArray(0);
1685 }
1686}
1687
Geoff Langc8058452014-02-03 12:04:11 -05001688void Context::detachTransformFeedback(GLuint transformFeedback)
1689{
Corentin Walleza2257da2016-04-19 16:43:12 -04001690 // Transform feedback detachment is handled by Context, because 0 is a valid
1691 // transform feedback, and a pointer to it must be passed from Context to State at
1692 // binding time.
1693
1694 // The OpenGL specification doesn't mention what should happen when the currently bound
1695 // transform feedback object is deleted. Since it is a container object, we treat it like
1696 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001697 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04001698 {
1699 bindTransformFeedback(0);
1700 }
Geoff Langc8058452014-02-03 12:04:11 -05001701}
1702
Jamie Madilldc356042013-07-19 16:36:57 -04001703void Context::detachSampler(GLuint sampler)
1704{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001705 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001706}
1707
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001708void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1709{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001710 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001711}
1712
Jamie Madille29d1672013-07-19 16:36:57 -04001713void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1714{
Jamie Madill901b3792016-05-26 09:20:40 -04001715 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001716
1717 Sampler *samplerObject = getSampler(sampler);
1718 ASSERT(samplerObject);
1719
Geoff Lang69cce582015-09-17 13:20:36 -04001720 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001721 switch (pname)
1722 {
Geoff Lang69cce582015-09-17 13:20:36 -04001723 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1724 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1725 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1726 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1727 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1728 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1729 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1730 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1731 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1732 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1733 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001734 }
Geoff Lang69cce582015-09-17 13:20:36 -04001735 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001736}
1737
1738void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1739{
Jamie Madill901b3792016-05-26 09:20:40 -04001740 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001741
1742 Sampler *samplerObject = getSampler(sampler);
1743 ASSERT(samplerObject);
1744
Geoff Lang69cce582015-09-17 13:20:36 -04001745 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001746 switch (pname)
1747 {
Geoff Lang69cce582015-09-17 13:20:36 -04001748 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1749 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1750 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1751 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1752 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1753 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1754 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1755 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1756 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1757 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1758 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001759 }
Geoff Lang69cce582015-09-17 13:20:36 -04001760 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001761}
1762
Jamie Madill9675b802013-07-19 16:36:59 -04001763GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1764{
Jamie Madill901b3792016-05-26 09:20:40 -04001765 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001766
1767 Sampler *samplerObject = getSampler(sampler);
1768 ASSERT(samplerObject);
1769
Geoff Lang69cce582015-09-17 13:20:36 -04001770 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001771 switch (pname)
1772 {
Geoff Lang69cce582015-09-17 13:20:36 -04001773 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1774 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1775 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1776 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1777 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1778 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001779 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1780 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001781 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1782 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1783 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001784 }
Geoff Lang69cce582015-09-17 13:20:36 -04001785 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001786}
1787
1788GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1789{
Jamie Madill901b3792016-05-26 09:20:40 -04001790 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001791
1792 Sampler *samplerObject = getSampler(sampler);
1793 ASSERT(samplerObject);
1794
Geoff Lang69cce582015-09-17 13:20:36 -04001795 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001796 switch (pname)
1797 {
Geoff Lang69cce582015-09-17 13:20:36 -04001798 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1799 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1800 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1801 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1802 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1803 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1804 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1805 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1806 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1807 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1808 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001809 }
Geoff Lang69cce582015-09-17 13:20:36 -04001810 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001811}
1812
Olli Etuahof0fee072016-03-30 15:11:58 +03001813void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1814{
1815 gl::Program *programObject = getProgram(program);
1816 ASSERT(programObject != nullptr);
1817
1818 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1819 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1820}
1821
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001822void Context::initRendererString()
1823{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001824 std::ostringstream rendererString;
1825 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001826 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001827 rendererString << ")";
1828
Geoff Langcec35902014-04-16 10:52:36 -04001829 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001830}
1831
Geoff Langc0b9ef42014-07-02 10:02:37 -04001832const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001833{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001834 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001835}
1836
Geoff Langcec35902014-04-16 10:52:36 -04001837void Context::initExtensionStrings()
1838{
Geoff Lang493daf52014-07-03 13:38:44 -04001839 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001840
Geoff Langc0b9ef42014-07-02 10:02:37 -04001841 std::ostringstream combinedStringStream;
1842 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1843 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001844}
1845
Geoff Langc0b9ef42014-07-02 10:02:37 -04001846const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001847{
1848 return mExtensionString;
1849}
1850
Geoff Langc0b9ef42014-07-02 10:02:37 -04001851const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04001852{
1853 return mExtensionStrings[idx];
1854}
1855
1856size_t Context::getExtensionStringCount() const
1857{
1858 return mExtensionStrings.size();
1859}
1860
Olli Etuahoc3e55a42016-03-09 16:29:18 +02001861void Context::beginTransformFeedback(GLenum primitiveMode)
1862{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001863 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02001864 ASSERT(transformFeedback != nullptr);
1865 ASSERT(!transformFeedback->isPaused());
1866
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001867 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02001868}
1869
1870bool Context::hasActiveTransformFeedback(GLuint program) const
1871{
1872 for (auto pair : mTransformFeedbackMap)
1873 {
1874 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
1875 {
1876 return true;
1877 }
1878 }
1879 return false;
1880}
1881
Jamie Madill00ed7a12016-05-19 13:13:38 -04001882void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04001883{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001884 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04001885
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001886 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04001887
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001888 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07001889
Jamie Madill00ed7a12016-05-19 13:13:38 -04001890 if (mClientVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04001891 {
1892 // Disable ES3+ extensions
1893 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04001894 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02001895 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04001896 }
1897
Jamie Madill00ed7a12016-05-19 13:13:38 -04001898 if (mClientVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04001899 {
1900 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
1901 //mExtensions.sRGB = false;
1902 }
1903
Jamie Madill00ed7a12016-05-19 13:13:38 -04001904 // Some extensions are always available because they are implemented in the GL layer.
1905 mExtensions.bindUniformLocation = true;
1906 mExtensions.vertexArrayObject = true;
1907
1908 // Enable the no error extension if the context was created with the flag.
1909 mExtensions.noError = mSkipValidation;
1910
Geoff Lang70d0f492015-12-10 17:45:46 -05001911 // Explicitly enable GL_KHR_debug
1912 mExtensions.debug = true;
1913 mExtensions.maxDebugMessageLength = 1024;
1914 mExtensions.maxDebugLoggedMessages = 1024;
1915 mExtensions.maxDebugGroupStackDepth = 1024;
1916 mExtensions.maxLabelLength = 1024;
1917
Geoff Lang301d1612014-07-09 10:34:37 -04001918 // Apply implementation limits
1919 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04001920 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
1921 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
1922
1923 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04001924
Geoff Lang900013c2014-07-07 11:32:19 -04001925 mCaps.compressedTextureFormats.clear();
1926
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001927 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04001928 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
1929 {
1930 GLenum format = i->first;
1931 TextureCaps formatCaps = i->second;
1932
Geoff Lang5d601382014-07-22 15:14:06 -04001933 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04001934
Geoff Lang0d8b7242015-09-09 14:56:53 -04001935 // Update the format caps based on the client version and extensions.
1936 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
1937 // ES3.
1938 formatCaps.texturable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04001939 formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04001940 formatCaps.renderable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04001941 formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04001942 formatCaps.filterable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04001943 formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04001944
1945 // OpenGL ES does not support multisampling with integer formats
1946 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04001947 {
Geoff Langd87878e2014-09-19 15:42:59 -04001948 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04001949 }
Geoff Langd87878e2014-09-19 15:42:59 -04001950
1951 if (formatCaps.texturable && formatInfo.compressed)
1952 {
1953 mCaps.compressedTextureFormats.push_back(format);
1954 }
1955
1956 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04001957 }
1958}
1959
Jamie Madill1b94d432015-08-07 13:23:23 -04001960void Context::syncRendererState()
1961{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001962 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
1963 mImplementation->syncState(mGLState, dirtyBits);
1964 mGLState.clearDirtyBits();
1965 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04001966}
1967
Jamie Madillad9f24e2016-02-12 09:27:24 -05001968void Context::syncRendererState(const State::DirtyBits &bitMask,
1969 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04001970{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001971 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
1972 mImplementation->syncState(mGLState, dirtyBits);
1973 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001974
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001975 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04001976}
Jamie Madillc29968b2016-01-20 11:17:23 -05001977
1978void Context::blitFramebuffer(GLint srcX0,
1979 GLint srcY0,
1980 GLint srcX1,
1981 GLint srcY1,
1982 GLint dstX0,
1983 GLint dstY0,
1984 GLint dstX1,
1985 GLint dstY1,
1986 GLbitfield mask,
1987 GLenum filter)
1988{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001989 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05001990 ASSERT(drawFramebuffer);
1991
1992 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
1993 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
1994
Jamie Madillad9f24e2016-02-12 09:27:24 -05001995 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05001996
Jamie Madill8415b5f2016-04-26 13:41:39 -04001997 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998}
Jamie Madillc29968b2016-01-20 11:17:23 -05001999
2000void Context::clear(GLbitfield mask)
2001{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002002 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002003 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002004}
2005
2006void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2007{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002008 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002009 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2010 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002011}
2012
2013void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2014{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002015 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002016 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2017 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002018}
2019
2020void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2021{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002022 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002023 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2024 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002025}
2026
2027void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2028{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002029 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002030 ASSERT(framebufferObject);
2031
2032 // If a buffer is not present, the clear has no effect
2033 if (framebufferObject->getDepthbuffer() == nullptr &&
2034 framebufferObject->getStencilbuffer() == nullptr)
2035 {
2036 return;
2037 }
2038
Jamie Madillad9f24e2016-02-12 09:27:24 -05002039 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002040 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2041 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002042}
2043
2044void Context::readPixels(GLint x,
2045 GLint y,
2046 GLsizei width,
2047 GLsizei height,
2048 GLenum format,
2049 GLenum type,
2050 GLvoid *pixels)
2051{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002052 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002053
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002054 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002055 ASSERT(framebufferObject);
2056
2057 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002058 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002059}
2060
2061void Context::copyTexImage2D(GLenum target,
2062 GLint level,
2063 GLenum internalformat,
2064 GLint x,
2065 GLint y,
2066 GLsizei width,
2067 GLsizei height,
2068 GLint border)
2069{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002070 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002071 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002072
Jamie Madillc29968b2016-01-20 11:17:23 -05002073 Rectangle sourceArea(x, y, width, height);
2074
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002075 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002076 Texture *texture =
2077 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002078 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002079}
2080
2081void Context::copyTexSubImage2D(GLenum target,
2082 GLint level,
2083 GLint xoffset,
2084 GLint yoffset,
2085 GLint x,
2086 GLint y,
2087 GLsizei width,
2088 GLsizei height)
2089{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002090 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002091 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002092
Jamie Madillc29968b2016-01-20 11:17:23 -05002093 Offset destOffset(xoffset, yoffset, 0);
2094 Rectangle sourceArea(x, y, width, height);
2095
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002096 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002097 Texture *texture =
2098 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002099 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002100}
2101
2102void Context::copyTexSubImage3D(GLenum target,
2103 GLint level,
2104 GLint xoffset,
2105 GLint yoffset,
2106 GLint zoffset,
2107 GLint x,
2108 GLint y,
2109 GLsizei width,
2110 GLsizei height)
2111{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002112 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002113 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002114
Jamie Madillc29968b2016-01-20 11:17:23 -05002115 Offset destOffset(xoffset, yoffset, zoffset);
2116 Rectangle sourceArea(x, y, width, height);
2117
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002118 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002119 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002120 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002121}
2122
2123void Context::framebufferTexture2D(GLenum target,
2124 GLenum attachment,
2125 GLenum textarget,
2126 GLuint texture,
2127 GLint level)
2128{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002129 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002130 ASSERT(framebuffer);
2131
2132 if (texture != 0)
2133 {
2134 Texture *textureObj = getTexture(texture);
2135
2136 ImageIndex index = ImageIndex::MakeInvalid();
2137
2138 if (textarget == GL_TEXTURE_2D)
2139 {
2140 index = ImageIndex::Make2D(level);
2141 }
2142 else
2143 {
2144 ASSERT(IsCubeMapTextureTarget(textarget));
2145 index = ImageIndex::MakeCube(textarget, level);
2146 }
2147
2148 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2149 }
2150 else
2151 {
2152 framebuffer->resetAttachment(attachment);
2153 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002154
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002155 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002156}
2157
2158void Context::framebufferRenderbuffer(GLenum target,
2159 GLenum attachment,
2160 GLenum renderbuffertarget,
2161 GLuint renderbuffer)
2162{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002163 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002164 ASSERT(framebuffer);
2165
2166 if (renderbuffer != 0)
2167 {
2168 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2169 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2170 renderbufferObject);
2171 }
2172 else
2173 {
2174 framebuffer->resetAttachment(attachment);
2175 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002176
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002178}
2179
2180void Context::framebufferTextureLayer(GLenum target,
2181 GLenum attachment,
2182 GLuint texture,
2183 GLint level,
2184 GLint layer)
2185{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002186 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002187 ASSERT(framebuffer);
2188
2189 if (texture != 0)
2190 {
2191 Texture *textureObject = getTexture(texture);
2192
2193 ImageIndex index = ImageIndex::MakeInvalid();
2194
2195 if (textureObject->getTarget() == GL_TEXTURE_3D)
2196 {
2197 index = ImageIndex::Make3D(level, layer);
2198 }
2199 else
2200 {
2201 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2202 index = ImageIndex::Make2DArray(level, layer);
2203 }
2204
2205 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2206 }
2207 else
2208 {
2209 framebuffer->resetAttachment(attachment);
2210 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002211
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002212 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002213}
2214
2215void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2216{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002217 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002218 ASSERT(framebuffer);
2219 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002220 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002221}
2222
2223void Context::readBuffer(GLenum mode)
2224{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002225 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002226 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002227 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002228}
2229
2230void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2231{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002232 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002233 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002234
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002235 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002236 ASSERT(framebuffer);
2237
2238 // The specification isn't clear what should be done when the framebuffer isn't complete.
2239 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002240 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002241}
2242
2243void Context::invalidateFramebuffer(GLenum target,
2244 GLsizei numAttachments,
2245 const GLenum *attachments)
2246{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002247 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002248 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002249
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002250 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002251 ASSERT(framebuffer);
2252
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002253 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002254 {
Jamie Madill437fa652016-05-03 15:13:24 -04002255 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002256 }
Jamie Madill437fa652016-05-03 15:13:24 -04002257
2258 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002259}
2260
2261void Context::invalidateSubFramebuffer(GLenum target,
2262 GLsizei numAttachments,
2263 const GLenum *attachments,
2264 GLint x,
2265 GLint y,
2266 GLsizei width,
2267 GLsizei height)
2268{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002269 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002270 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002271
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002272 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002273 ASSERT(framebuffer);
2274
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002275 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002276 {
Jamie Madill437fa652016-05-03 15:13:24 -04002277 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002278 }
Jamie Madill437fa652016-05-03 15:13:24 -04002279
2280 Rectangle area(x, y, width, height);
2281 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002282}
2283
Jamie Madill73a84962016-02-12 09:27:23 -05002284void Context::texImage2D(GLenum target,
2285 GLint level,
2286 GLint internalformat,
2287 GLsizei width,
2288 GLsizei height,
2289 GLint border,
2290 GLenum format,
2291 GLenum type,
2292 const GLvoid *pixels)
2293{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002294 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002295
2296 Extents size(width, height, 1);
2297 Texture *texture =
2298 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002299 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002300 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002301}
2302
2303void Context::texImage3D(GLenum target,
2304 GLint level,
2305 GLint internalformat,
2306 GLsizei width,
2307 GLsizei height,
2308 GLsizei depth,
2309 GLint border,
2310 GLenum format,
2311 GLenum type,
2312 const GLvoid *pixels)
2313{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002314 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002315
2316 Extents size(width, height, depth);
2317 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002318 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002319 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002320}
2321
2322void Context::texSubImage2D(GLenum target,
2323 GLint level,
2324 GLint xoffset,
2325 GLint yoffset,
2326 GLsizei width,
2327 GLsizei height,
2328 GLenum format,
2329 GLenum type,
2330 const GLvoid *pixels)
2331{
2332 // Zero sized uploads are valid but no-ops
2333 if (width == 0 || height == 0)
2334 {
2335 return;
2336 }
2337
Jamie Madillad9f24e2016-02-12 09:27:24 -05002338 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002339
2340 Box area(xoffset, yoffset, 0, width, height, 1);
2341 Texture *texture =
2342 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002343 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002344 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002345}
2346
2347void Context::texSubImage3D(GLenum target,
2348 GLint level,
2349 GLint xoffset,
2350 GLint yoffset,
2351 GLint zoffset,
2352 GLsizei width,
2353 GLsizei height,
2354 GLsizei depth,
2355 GLenum format,
2356 GLenum type,
2357 const GLvoid *pixels)
2358{
2359 // Zero sized uploads are valid but no-ops
2360 if (width == 0 || height == 0 || depth == 0)
2361 {
2362 return;
2363 }
2364
Jamie Madillad9f24e2016-02-12 09:27:24 -05002365 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002366
2367 Box area(xoffset, yoffset, zoffset, width, height, depth);
2368 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002369 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002370 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002371}
2372
2373void Context::compressedTexImage2D(GLenum target,
2374 GLint level,
2375 GLenum internalformat,
2376 GLsizei width,
2377 GLsizei height,
2378 GLint border,
2379 GLsizei imageSize,
2380 const GLvoid *data)
2381{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002382 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002383
2384 Extents size(width, height, 1);
2385 Texture *texture =
2386 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002387 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2388 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002389 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002390}
2391
2392void Context::compressedTexImage3D(GLenum target,
2393 GLint level,
2394 GLenum internalformat,
2395 GLsizei width,
2396 GLsizei height,
2397 GLsizei depth,
2398 GLint border,
2399 GLsizei imageSize,
2400 const GLvoid *data)
2401{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002402 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002403
2404 Extents size(width, height, depth);
2405 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002406 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2407 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002408 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002409}
2410
2411void Context::compressedTexSubImage2D(GLenum target,
2412 GLint level,
2413 GLint xoffset,
2414 GLint yoffset,
2415 GLsizei width,
2416 GLsizei height,
2417 GLenum format,
2418 GLsizei imageSize,
2419 const GLvoid *data)
2420{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002421 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002422
2423 Box area(xoffset, yoffset, 0, width, height, 1);
2424 Texture *texture =
2425 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002426 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2427 format, imageSize,
2428 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002429}
2430
2431void Context::compressedTexSubImage3D(GLenum target,
2432 GLint level,
2433 GLint xoffset,
2434 GLint yoffset,
2435 GLint zoffset,
2436 GLsizei width,
2437 GLsizei height,
2438 GLsizei depth,
2439 GLenum format,
2440 GLsizei imageSize,
2441 const GLvoid *data)
2442{
2443 // Zero sized uploads are valid but no-ops
2444 if (width == 0 || height == 0)
2445 {
2446 return;
2447 }
2448
Jamie Madillad9f24e2016-02-12 09:27:24 -05002449 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002450
2451 Box area(xoffset, yoffset, zoffset, width, height, depth);
2452 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002453 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2454 format, imageSize,
2455 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002456}
2457
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002458void Context::generateMipmap(GLenum target)
2459{
2460 Texture *texture = getTargetTexture(target);
2461 handleError(texture->generateMipmap());
2462}
2463
Olli Etuaho4f667482016-03-30 15:56:35 +03002464void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2465{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002466 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002467 ASSERT(buffer);
2468
2469 if (!buffer->isMapped())
2470 {
2471 *params = nullptr;
2472 }
2473 else
2474 {
2475 *params = buffer->getMapPointer();
2476 }
2477}
2478
2479GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002481 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002482 ASSERT(buffer);
2483
2484 Error error = buffer->map(access);
2485 if (error.isError())
2486 {
Jamie Madill437fa652016-05-03 15:13:24 -04002487 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002488 return nullptr;
2489 }
2490
2491 return buffer->getMapPointer();
2492}
2493
2494GLboolean Context::unmapBuffer(GLenum target)
2495{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002496 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002497 ASSERT(buffer);
2498
2499 GLboolean result;
2500 Error error = buffer->unmap(&result);
2501 if (error.isError())
2502 {
Jamie Madill437fa652016-05-03 15:13:24 -04002503 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002504 return GL_FALSE;
2505 }
2506
2507 return result;
2508}
2509
2510GLvoid *Context::mapBufferRange(GLenum target,
2511 GLintptr offset,
2512 GLsizeiptr length,
2513 GLbitfield access)
2514{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002515 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002516 ASSERT(buffer);
2517
2518 Error error = buffer->mapRange(offset, length, access);
2519 if (error.isError())
2520 {
Jamie Madill437fa652016-05-03 15:13:24 -04002521 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002522 return nullptr;
2523 }
2524
2525 return buffer->getMapPointer();
2526}
2527
2528void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2529{
2530 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2531}
2532
Jamie Madillad9f24e2016-02-12 09:27:24 -05002533void Context::syncStateForReadPixels()
2534{
2535 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2536}
2537
2538void Context::syncStateForTexImage()
2539{
2540 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2541}
2542
2543void Context::syncStateForClear()
2544{
2545 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2546}
2547
2548void Context::syncStateForBlit()
2549{
2550 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2551}
2552
Jamie Madillc20ab272016-06-09 07:20:46 -07002553void Context::activeTexture(GLenum texture)
2554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002555 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002556}
2557
2558void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2559{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002560 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07002561}
2562
2563void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002565 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002566}
2567
2568void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2569{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002570 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002571}
2572
2573void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2574{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002575 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002576}
2577
2578void Context::clearDepthf(GLclampf depth)
2579{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002580 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07002581}
2582
2583void Context::clearStencil(GLint s)
2584{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002585 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07002586}
2587
2588void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2589{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002590 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002591}
2592
2593void Context::cullFace(GLenum mode)
2594{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002595 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002596}
2597
2598void Context::depthFunc(GLenum func)
2599{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002600 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07002601}
2602
2603void Context::depthMask(GLboolean flag)
2604{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002605 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002606}
2607
2608void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2609{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07002611}
2612
2613void Context::disable(GLenum cap)
2614{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002615 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002616}
2617
2618void Context::disableVertexAttribArray(GLuint index)
2619{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002620 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002621}
2622
2623void Context::enable(GLenum cap)
2624{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002626}
2627
2628void Context::enableVertexAttribArray(GLuint index)
2629{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002630 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002631}
2632
2633void Context::frontFace(GLenum mode)
2634{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002635 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002636}
2637
2638void Context::hint(GLenum target, GLenum mode)
2639{
2640 switch (target)
2641 {
2642 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002643 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002644 break;
2645
2646 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002647 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002648 break;
2649
2650 default:
2651 UNREACHABLE();
2652 return;
2653 }
2654}
2655
2656void Context::lineWidth(GLfloat width)
2657{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002658 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07002659}
2660
2661void Context::pixelStorei(GLenum pname, GLint param)
2662{
2663 switch (pname)
2664 {
2665 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002666 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002667 break;
2668
2669 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002670 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002671 break;
2672
2673 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002674 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002675 break;
2676
2677 case GL_UNPACK_ROW_LENGTH:
2678 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002679 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002680 break;
2681
2682 case GL_UNPACK_IMAGE_HEIGHT:
2683 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002684 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002685 break;
2686
2687 case GL_UNPACK_SKIP_IMAGES:
2688 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002689 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002690 break;
2691
2692 case GL_UNPACK_SKIP_ROWS:
2693 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002694 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002695 break;
2696
2697 case GL_UNPACK_SKIP_PIXELS:
2698 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002699 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002700 break;
2701
2702 case GL_PACK_ROW_LENGTH:
2703 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002704 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002705 break;
2706
2707 case GL_PACK_SKIP_ROWS:
2708 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002709 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002710 break;
2711
2712 case GL_PACK_SKIP_PIXELS:
2713 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002714 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002715 break;
2716
2717 default:
2718 UNREACHABLE();
2719 return;
2720 }
2721}
2722
2723void Context::polygonOffset(GLfloat factor, GLfloat units)
2724{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002725 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07002726}
2727
2728void Context::sampleCoverage(GLclampf value, GLboolean invert)
2729{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002730 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002731}
2732
2733void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2734{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002736}
2737
2738void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2739{
2740 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2741 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002742 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002743 }
2744
2745 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2746 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002747 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002748 }
2749}
2750
2751void Context::stencilMaskSeparate(GLenum face, GLuint mask)
2752{
2753 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2754 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002755 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002756 }
2757
2758 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2759 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002760 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002761 }
2762}
2763
2764void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
2765{
2766 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2767 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002768 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002769 }
2770
2771 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2772 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002773 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002774 }
2775}
2776
2777void Context::vertexAttrib1f(GLuint index, GLfloat x)
2778{
2779 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002780 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002781}
2782
2783void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
2784{
2785 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002787}
2788
2789void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
2790{
2791 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002792 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002793}
2794
2795void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
2796{
2797 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002799}
2800
2801void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
2802{
2803 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002805}
2806
2807void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
2808{
2809 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002810 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002811}
2812
2813void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2814{
2815 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002816 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002817}
2818
2819void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
2820{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07002822}
2823
2824void Context::vertexAttribPointer(GLuint index,
2825 GLint size,
2826 GLenum type,
2827 GLboolean normalized,
2828 GLsizei stride,
2829 const GLvoid *ptr)
2830{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002831 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
2832 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07002833}
2834
2835void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
2836{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002837 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002838}
2839
2840void Context::vertexAttribIPointer(GLuint index,
2841 GLint size,
2842 GLenum type,
2843 GLsizei stride,
2844 const GLvoid *pointer)
2845{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
2847 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07002848}
2849
2850void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
2851{
2852 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002853 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002854}
2855
2856void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
2857{
2858 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002859 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002860}
2861
2862void Context::vertexAttribI4iv(GLuint index, const GLint *v)
2863{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002864 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07002865}
2866
2867void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
2868{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07002870}
2871
2872void Context::debugMessageControl(GLenum source,
2873 GLenum type,
2874 GLenum severity,
2875 GLsizei count,
2876 const GLuint *ids,
2877 GLboolean enabled)
2878{
2879 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002880 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
2881 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07002882}
2883
2884void Context::debugMessageInsert(GLenum source,
2885 GLenum type,
2886 GLuint id,
2887 GLenum severity,
2888 GLsizei length,
2889 const GLchar *buf)
2890{
2891 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002892 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07002893}
2894
2895void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
2896{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07002898}
2899
2900GLuint Context::getDebugMessageLog(GLuint count,
2901 GLsizei bufSize,
2902 GLenum *sources,
2903 GLenum *types,
2904 GLuint *ids,
2905 GLenum *severities,
2906 GLsizei *lengths,
2907 GLchar *messageLog)
2908{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002909 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
2910 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07002911}
2912
2913void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
2914{
2915 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002916 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07002917}
2918
2919void Context::popDebugGroup()
2920{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07002922}
2923
Jamie Madillc29968b2016-01-20 11:17:23 -05002924} // namespace gl