blob: c867da5f862ebd22ba4f1a60fe2d44d06e4687a5 [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>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030048std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
49 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
68std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
69 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
176}
177
178bool GetDebug(const egl::AttributeMap &attribs)
179{
180 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
181}
182
183bool GetNoError(const egl::AttributeMap &attribs)
184{
185 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
186}
187
Geoff Langc287ea62016-09-16 14:46:51 -0400188bool GetWebGLContext(const egl::AttributeMap &attribs)
189{
190 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
191}
192
Geoff Langf41a7152016-09-19 15:11:17 -0400193bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
194{
195 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
196}
197
Martin Radev9d901792016-07-15 15:58:58 +0300198std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
199{
200 std::string labelName;
201 if (label != nullptr)
202 {
203 size_t labelLength = length < 0 ? strlen(label) : length;
204 labelName = std::string(label, labelLength);
205 }
206 return labelName;
207}
208
209void GetObjectLabelBase(const std::string &objectLabel,
210 GLsizei bufSize,
211 GLsizei *length,
212 GLchar *label)
213{
214 size_t writeLength = objectLabel.length();
215 if (label != nullptr && bufSize > 0)
216 {
217 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
218 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
219 label[writeLength] = '\0';
220 }
221
222 if (length != nullptr)
223 {
224 *length = static_cast<GLsizei>(writeLength);
225 }
226}
227
Geoff Langf6db0982015-08-25 13:04:00 -0400228} // anonymous namespace
229
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000230namespace gl
231{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000232
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400233Context::Context(rx::EGLImplFactory *implFactory,
234 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400235 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500236 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300237
Geoff Langeb66a6e2016-10-31 13:06:12 -0400238 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700239 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500240 mCaps,
241 mTextureCaps,
242 mExtensions,
243 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500244 mLimitations,
245 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700246 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500247 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400248 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500249 mClientType(EGL_OPENGL_ES_API),
250 mHasBeenCurrent(false),
251 mContextLost(false),
252 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700253 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500254 mResetStrategy(GetResetStrategy(attribs)),
255 mRobustAccess(GetRobustAccess(attribs)),
256 mCurrentSurface(nullptr),
257 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000258{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500259 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000260
Geoff Langc287ea62016-09-16 14:46:51 -0400261 initCaps(GetWebGLContext(attribs));
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700262 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400263
Geoff Langeb66a6e2016-10-31 13:06:12 -0400264 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langf41a7152016-09-19 15:11:17 -0400265 GetBindGeneratesResource(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100266
Shannon Woods53a94a82014-06-24 15:20:36 -0400267 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400268
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400269 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000270 {
271 mResourceManager = shareContext->mResourceManager;
272 mResourceManager->addRef();
273 }
274 else
275 {
Jamie Madill901b3792016-05-26 09:20:40 -0400276 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000277 }
278
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700279 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400280
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281 // [OpenGL ES 2.0.24] section 3.7 page 83:
282 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
283 // and cube map texture state vectors respectively associated with them.
284 // In order that access to these initial textures not be lost, they are treated as texture
285 // objects all of whose names are 0.
286
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400287 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500288 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500289
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400290 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500291 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400292
Geoff Langeb66a6e2016-10-31 13:06:12 -0400293 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400294 {
295 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400296 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500297 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400298
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400299 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500300 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400301 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000302
Ian Ewellbda75592016-04-18 17:25:54 -0400303 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
304 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400305 Texture *zeroTextureExternal =
306 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400307 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
308 }
309
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700310 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500311
Jamie Madill57a89722013-07-02 11:57:03 -0400312 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000313 bindArrayBuffer(0);
314 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400315
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000316 bindRenderbuffer(0);
317
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000318 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400319 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000320 {
321 bindIndexedUniformBuffer(0, i, 0, -1);
322 }
323
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000324 bindCopyReadBuffer(0);
325 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000326 bindPixelPackBuffer(0);
327 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000328
Geoff Langeb66a6e2016-10-31 13:06:12 -0400329 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400330 {
331 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
332 // In the initial state, a default transform feedback object is bound and treated as
333 // a transform feedback object with a name of zero. That object is bound any time
334 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400335 bindTransformFeedback(0);
336 }
Geoff Langc8058452014-02-03 12:04:11 -0500337
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700338 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500339
340 // Initialize dirty bit masks
341 // TODO(jmadill): additional ES3 state
342 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
343 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
344 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
345 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
346 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
347 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400348 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500349 // No dirty objects.
350
351 // Readpixels uses the pack state and read FBO
352 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
353 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
354 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
355 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
356 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400357 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500358 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
359
360 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
361 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
362 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
363 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
364 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
365 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
366 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
367 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
368 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
369 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
370 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
371 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
372
373 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
374 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700375 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500376 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
377 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400378
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400379 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000380}
381
382Context::~Context()
383{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700384 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000385
Corentin Wallez37c39792015-08-20 14:19:46 -0400386 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000387 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400388 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400389 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400390 {
391 SafeDelete(framebuffer.second);
392 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000393 }
394
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400397 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398 }
399
Corentin Wallez80b24112015-08-25 16:41:57 -0400400 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400402 if (query.second != nullptr)
403 {
404 query.second->release();
405 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400409 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400411 }
412
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500414 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500415 if (transformFeedback.second != nullptr)
416 {
417 transformFeedback.second->release();
418 }
Geoff Langc8058452014-02-03 12:04:11 -0500419 }
420
Jamie Madilldedd7b92014-11-05 16:30:36 -0500421 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400422 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500423 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400424 }
425 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426
Corentin Wallez51706ea2015-08-07 14:39:22 -0400427 if (mCurrentSurface != nullptr)
428 {
429 releaseSurface();
430 }
431
Jamie Madill1e9ae072014-11-06 15:27:21 -0500432 if (mResourceManager)
433 {
434 mResourceManager->release();
435 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500436
437 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000438}
439
daniel@transgaming.comad629872012-11-28 19:32:06 +0000440void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441{
Jamie Madill77a72f62015-04-14 11:18:32 -0400442 ASSERT(surface != nullptr);
443
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000444 if (!mHasBeenCurrent)
445 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400447 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000448
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700449 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
450 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451
452 mHasBeenCurrent = true;
453 }
454
Jamie Madill1b94d432015-08-07 13:23:23 -0400455 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700456 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400457
Corentin Wallez51706ea2015-08-07 14:39:22 -0400458 if (mCurrentSurface)
459 {
460 releaseSurface();
461 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000462 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400463 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000464
Corentin Wallez37c39792015-08-20 14:19:46 -0400465 // Update default framebuffer, the binding of the previous default
466 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400467 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400468 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700469 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400470 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700471 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400472 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700473 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400474 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700475 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400476 }
477 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400478 }
Ian Ewell292f0052016-02-04 10:37:32 -0500479
480 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700481 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000482}
483
Jamie Madill77a72f62015-04-14 11:18:32 -0400484void Context::releaseSurface()
485{
Corentin Wallez37c39792015-08-20 14:19:46 -0400486 ASSERT(mCurrentSurface != nullptr);
487
488 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400489 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400490 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700491 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400492 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700493 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400494 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700495 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400496 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700497 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400498 }
499 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400500 }
501
Corentin Wallez51706ea2015-08-07 14:39:22 -0400502 mCurrentSurface->setIsCurrent(false);
503 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400504}
505
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000506GLuint Context::createBuffer()
507{
508 return mResourceManager->createBuffer();
509}
510
511GLuint Context::createProgram()
512{
Jamie Madill901b3792016-05-26 09:20:40 -0400513 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000514}
515
516GLuint Context::createShader(GLenum type)
517{
Jamie Madill901b3792016-05-26 09:20:40 -0400518 return mResourceManager->createShader(mImplementation.get(),
519 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000520}
521
522GLuint Context::createTexture()
523{
524 return mResourceManager->createTexture();
525}
526
527GLuint Context::createRenderbuffer()
528{
529 return mResourceManager->createRenderbuffer();
530}
531
Geoff Lang882033e2014-09-30 11:26:07 -0400532GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400533{
Jamie Madill901b3792016-05-26 09:20:40 -0400534 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400535
Cooper Partind8e62a32015-01-29 15:21:25 -0800536 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400537}
538
Sami Väisänene45e53b2016-05-25 10:36:04 +0300539GLuint Context::createPaths(GLsizei range)
540{
541 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
542 if (resultOrError.isError())
543 {
544 handleError(resultOrError.getError());
545 return 0;
546 }
547 return resultOrError.getResult();
548}
549
Jamie Madill57a89722013-07-02 11:57:03 -0400550GLuint Context::createVertexArray()
551{
Geoff Lang36167ab2015-12-07 10:27:14 -0500552 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
553 mVertexArrayMap[vertexArray] = nullptr;
554 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400555}
556
Jamie Madilldc356042013-07-19 16:36:57 -0400557GLuint Context::createSampler()
558{
559 return mResourceManager->createSampler();
560}
561
Geoff Langc8058452014-02-03 12:04:11 -0500562GLuint Context::createTransformFeedback()
563{
Geoff Lang36167ab2015-12-07 10:27:14 -0500564 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
565 mTransformFeedbackMap[transformFeedback] = nullptr;
566 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500567}
568
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000569// Returns an unused framebuffer name
570GLuint Context::createFramebuffer()
571{
572 GLuint handle = mFramebufferHandleAllocator.allocate();
573
574 mFramebufferMap[handle] = NULL;
575
576 return handle;
577}
578
Jamie Madill33dc8432013-07-26 11:55:05 -0400579GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580{
Jamie Madill33dc8432013-07-26 11:55:05 -0400581 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000582
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400583 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000584
585 return handle;
586}
587
588// Returns an unused query name
589GLuint Context::createQuery()
590{
591 GLuint handle = mQueryHandleAllocator.allocate();
592
593 mQueryMap[handle] = NULL;
594
595 return handle;
596}
597
598void Context::deleteBuffer(GLuint buffer)
599{
600 if (mResourceManager->getBuffer(buffer))
601 {
602 detachBuffer(buffer);
603 }
Jamie Madill893ab082014-05-16 16:56:10 -0400604
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605 mResourceManager->deleteBuffer(buffer);
606}
607
608void Context::deleteShader(GLuint shader)
609{
610 mResourceManager->deleteShader(shader);
611}
612
613void Context::deleteProgram(GLuint program)
614{
615 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616}
617
618void Context::deleteTexture(GLuint texture)
619{
620 if (mResourceManager->getTexture(texture))
621 {
622 detachTexture(texture);
623 }
624
625 mResourceManager->deleteTexture(texture);
626}
627
628void Context::deleteRenderbuffer(GLuint renderbuffer)
629{
630 if (mResourceManager->getRenderbuffer(renderbuffer))
631 {
632 detachRenderbuffer(renderbuffer);
633 }
Jamie Madill893ab082014-05-16 16:56:10 -0400634
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000635 mResourceManager->deleteRenderbuffer(renderbuffer);
636}
637
Jamie Madillcd055f82013-07-26 11:55:15 -0400638void Context::deleteFenceSync(GLsync fenceSync)
639{
640 // The spec specifies the underlying Fence object is not deleted until all current
641 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
642 // and since our API is currently designed for being called from a single thread, we can delete
643 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700644 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400645}
646
Sami Väisänene45e53b2016-05-25 10:36:04 +0300647void Context::deletePaths(GLuint first, GLsizei range)
648{
649 mResourceManager->deletePaths(first, range);
650}
651
652bool Context::hasPathData(GLuint path) const
653{
654 const auto *pathObj = mResourceManager->getPath(path);
655 if (pathObj == nullptr)
656 return false;
657
658 return pathObj->hasPathData();
659}
660
661bool Context::hasPath(GLuint path) const
662{
663 return mResourceManager->hasPath(path);
664}
665
666void Context::setPathCommands(GLuint path,
667 GLsizei numCommands,
668 const GLubyte *commands,
669 GLsizei numCoords,
670 GLenum coordType,
671 const void *coords)
672{
673 auto *pathObject = mResourceManager->getPath(path);
674
675 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
676}
677
678void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
679{
680 auto *pathObj = mResourceManager->getPath(path);
681
682 switch (pname)
683 {
684 case GL_PATH_STROKE_WIDTH_CHROMIUM:
685 pathObj->setStrokeWidth(value);
686 break;
687 case GL_PATH_END_CAPS_CHROMIUM:
688 pathObj->setEndCaps(static_cast<GLenum>(value));
689 break;
690 case GL_PATH_JOIN_STYLE_CHROMIUM:
691 pathObj->setJoinStyle(static_cast<GLenum>(value));
692 break;
693 case GL_PATH_MITER_LIMIT_CHROMIUM:
694 pathObj->setMiterLimit(value);
695 break;
696 case GL_PATH_STROKE_BOUND_CHROMIUM:
697 pathObj->setStrokeBound(value);
698 break;
699 default:
700 UNREACHABLE();
701 break;
702 }
703}
704
705void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
706{
707 const auto *pathObj = mResourceManager->getPath(path);
708
709 switch (pname)
710 {
711 case GL_PATH_STROKE_WIDTH_CHROMIUM:
712 *value = pathObj->getStrokeWidth();
713 break;
714 case GL_PATH_END_CAPS_CHROMIUM:
715 *value = static_cast<GLfloat>(pathObj->getEndCaps());
716 break;
717 case GL_PATH_JOIN_STYLE_CHROMIUM:
718 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
719 break;
720 case GL_PATH_MITER_LIMIT_CHROMIUM:
721 *value = pathObj->getMiterLimit();
722 break;
723 case GL_PATH_STROKE_BOUND_CHROMIUM:
724 *value = pathObj->getStrokeBound();
725 break;
726 default:
727 UNREACHABLE();
728 break;
729 }
730}
731
732void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
733{
734 mGLState.setPathStencilFunc(func, ref, mask);
735}
736
Jamie Madill57a89722013-07-02 11:57:03 -0400737void Context::deleteVertexArray(GLuint vertexArray)
738{
Geoff Lang36167ab2015-12-07 10:27:14 -0500739 auto iter = mVertexArrayMap.find(vertexArray);
740 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000741 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500742 VertexArray *vertexArrayObject = iter->second;
743 if (vertexArrayObject != nullptr)
744 {
745 detachVertexArray(vertexArray);
746 delete vertexArrayObject;
747 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000748
Geoff Lang36167ab2015-12-07 10:27:14 -0500749 mVertexArrayMap.erase(iter);
750 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400751 }
752}
753
Jamie Madilldc356042013-07-19 16:36:57 -0400754void Context::deleteSampler(GLuint sampler)
755{
756 if (mResourceManager->getSampler(sampler))
757 {
758 detachSampler(sampler);
759 }
760
761 mResourceManager->deleteSampler(sampler);
762}
763
Geoff Langc8058452014-02-03 12:04:11 -0500764void Context::deleteTransformFeedback(GLuint transformFeedback)
765{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500766 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500767 if (iter != mTransformFeedbackMap.end())
768 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500769 TransformFeedback *transformFeedbackObject = iter->second;
770 if (transformFeedbackObject != nullptr)
771 {
772 detachTransformFeedback(transformFeedback);
773 transformFeedbackObject->release();
774 }
775
Geoff Lang50b3fe82015-12-08 14:49:12 +0000776 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500777 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500778 }
779}
780
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781void Context::deleteFramebuffer(GLuint framebuffer)
782{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500783 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784
785 if (framebufferObject != mFramebufferMap.end())
786 {
787 detachFramebuffer(framebuffer);
788
789 mFramebufferHandleAllocator.release(framebufferObject->first);
790 delete framebufferObject->second;
791 mFramebufferMap.erase(framebufferObject);
792 }
793}
794
Jamie Madill33dc8432013-07-26 11:55:05 -0400795void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500797 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798
Jamie Madill33dc8432013-07-26 11:55:05 -0400799 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400801 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400803 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804 }
805}
806
807void Context::deleteQuery(GLuint query)
808{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500809 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810 if (queryObject != mQueryMap.end())
811 {
812 mQueryHandleAllocator.release(queryObject->first);
813 if (queryObject->second)
814 {
815 queryObject->second->release();
816 }
817 mQueryMap.erase(queryObject);
818 }
819}
820
Geoff Lang70d0f492015-12-10 17:45:46 -0500821Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000822{
823 return mResourceManager->getBuffer(handle);
824}
825
Jamie Madill570f7c82014-07-03 10:38:54 -0400826Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827{
828 return mResourceManager->getTexture(handle);
829}
830
Geoff Lang70d0f492015-12-10 17:45:46 -0500831Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000832{
833 return mResourceManager->getRenderbuffer(handle);
834}
835
Jamie Madillcd055f82013-07-26 11:55:15 -0400836FenceSync *Context::getFenceSync(GLsync handle) const
837{
Minmin Gong794e0002015-04-07 18:31:54 -0700838 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400839}
840
Jamie Madill57a89722013-07-02 11:57:03 -0400841VertexArray *Context::getVertexArray(GLuint handle) const
842{
843 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500844 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400845}
846
Jamie Madilldc356042013-07-19 16:36:57 -0400847Sampler *Context::getSampler(GLuint handle) const
848{
849 return mResourceManager->getSampler(handle);
850}
851
Geoff Langc8058452014-02-03 12:04:11 -0500852TransformFeedback *Context::getTransformFeedback(GLuint handle) const
853{
Geoff Lang36167ab2015-12-07 10:27:14 -0500854 auto iter = mTransformFeedbackMap.find(handle);
855 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500856}
857
Geoff Lang70d0f492015-12-10 17:45:46 -0500858LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
859{
860 switch (identifier)
861 {
862 case GL_BUFFER:
863 return getBuffer(name);
864 case GL_SHADER:
865 return getShader(name);
866 case GL_PROGRAM:
867 return getProgram(name);
868 case GL_VERTEX_ARRAY:
869 return getVertexArray(name);
870 case GL_QUERY:
871 return getQuery(name);
872 case GL_TRANSFORM_FEEDBACK:
873 return getTransformFeedback(name);
874 case GL_SAMPLER:
875 return getSampler(name);
876 case GL_TEXTURE:
877 return getTexture(name);
878 case GL_RENDERBUFFER:
879 return getRenderbuffer(name);
880 case GL_FRAMEBUFFER:
881 return getFramebuffer(name);
882 default:
883 UNREACHABLE();
884 return nullptr;
885 }
886}
887
888LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
889{
890 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
891}
892
Martin Radev9d901792016-07-15 15:58:58 +0300893void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
894{
895 LabeledObject *object = getLabeledObject(identifier, name);
896 ASSERT(object != nullptr);
897
898 std::string labelName = GetObjectLabelFromPointer(length, label);
899 object->setLabel(labelName);
900}
901
902void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
903{
904 LabeledObject *object = getLabeledObjectFromPtr(ptr);
905 ASSERT(object != nullptr);
906
907 std::string labelName = GetObjectLabelFromPointer(length, label);
908 object->setLabel(labelName);
909}
910
911void Context::getObjectLabel(GLenum identifier,
912 GLuint name,
913 GLsizei bufSize,
914 GLsizei *length,
915 GLchar *label) const
916{
917 LabeledObject *object = getLabeledObject(identifier, name);
918 ASSERT(object != nullptr);
919
920 const std::string &objectLabel = object->getLabel();
921 GetObjectLabelBase(objectLabel, bufSize, length, label);
922}
923
924void Context::getObjectPtrLabel(const void *ptr,
925 GLsizei bufSize,
926 GLsizei *length,
927 GLchar *label) const
928{
929 LabeledObject *object = getLabeledObjectFromPtr(ptr);
930 ASSERT(object != nullptr);
931
932 const std::string &objectLabel = object->getLabel();
933 GetObjectLabelBase(objectLabel, bufSize, length, label);
934}
935
Jamie Madilldc356042013-07-19 16:36:57 -0400936bool Context::isSampler(GLuint samplerName) const
937{
938 return mResourceManager->isSampler(samplerName);
939}
940
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500941void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942{
Jamie Madill901b3792016-05-26 09:20:40 -0400943 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700944 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945}
946
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500947void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Jamie Madill901b3792016-05-26 09:20:40 -0400949 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700950 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jamie Madilldedd7b92014-11-05 16:30:36 -0500953void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500955 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000956
Jamie Madilldedd7b92014-11-05 16:30:36 -0500957 if (handle == 0)
958 {
959 texture = mZeroTextures[target].get();
960 }
961 else
962 {
Jamie Madill901b3792016-05-26 09:20:40 -0400963 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500964 }
965
966 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700967 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000968}
969
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500970void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500972 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700973 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974}
975
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500976void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500978 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700979 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980}
981
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500982void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983{
Jamie Madill901b3792016-05-26 09:20:40 -0400984 Renderbuffer *renderbuffer =
985 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700986 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000987}
988
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500989void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400990{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500991 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700992 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400993}
994
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500995void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400996{
Geoff Lang76b10c92014-09-05 16:28:14 -0400997 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400998 Sampler *sampler =
999 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001000 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001001}
1002
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001003void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001004{
Jamie Madill901b3792016-05-26 09:20:40 -04001005 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001007}
1008
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001009void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1010 GLuint index,
1011 GLintptr offset,
1012 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001013{
Jamie Madill901b3792016-05-26 09:20:40 -04001014 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001015 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001016}
1017
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001019{
Jamie Madill901b3792016-05-26 09:20:40 -04001020 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001021 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001022}
1023
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001024void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1025 GLuint index,
1026 GLintptr offset,
1027 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001028{
Jamie Madill901b3792016-05-26 09:20:40 -04001029 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001030 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001031}
1032
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001033void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001034{
Jamie Madill901b3792016-05-26 09:20:40 -04001035 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001036 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001037}
1038
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001039void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001040{
Jamie Madill901b3792016-05-26 09:20:40 -04001041 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001046{
Jamie Madill901b3792016-05-26 09:20:40 -04001047 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001052{
Jamie Madill901b3792016-05-26 09:20:40 -04001053 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001054 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001055}
1056
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001057void Context::useProgram(GLuint program)
1058{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001059 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001060}
1061
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001062void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001063{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001064 TransformFeedback *transformFeedback =
1065 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001066 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001067}
1068
Geoff Lang5aad9672014-09-08 11:10:42 -04001069Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001070{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001072 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001073
Geoff Lang5aad9672014-09-08 11:10:42 -04001074 // begin query
1075 Error error = queryObject->begin();
1076 if (error.isError())
1077 {
1078 return error;
1079 }
1080
1081 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083
Geoff Lang5aad9672014-09-08 11:10:42 -04001084 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085}
1086
Geoff Lang5aad9672014-09-08 11:10:42 -04001087Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001089 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001090 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Geoff Lang5aad9672014-09-08 11:10:42 -04001092 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093
Geoff Lang5aad9672014-09-08 11:10:42 -04001094 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001095 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001096
1097 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098}
1099
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001100Error Context::queryCounter(GLuint id, GLenum target)
1101{
1102 ASSERT(target == GL_TIMESTAMP_EXT);
1103
1104 Query *queryObject = getQuery(id, true, target);
1105 ASSERT(queryObject);
1106
1107 return queryObject->queryCounter();
1108}
1109
1110void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1111{
1112 switch (pname)
1113 {
1114 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001115 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001116 break;
1117 case GL_QUERY_COUNTER_BITS_EXT:
1118 switch (target)
1119 {
1120 case GL_TIME_ELAPSED_EXT:
1121 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1122 break;
1123 case GL_TIMESTAMP_EXT:
1124 params[0] = getExtensions().queryCounterBitsTimestamp;
1125 break;
1126 default:
1127 UNREACHABLE();
1128 params[0] = 0;
1129 break;
1130 }
1131 break;
1132 default:
1133 UNREACHABLE();
1134 return;
1135 }
1136}
1137
Geoff Lang2186c382016-10-14 10:54:54 -04001138void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001139{
Geoff Lang2186c382016-10-14 10:54:54 -04001140 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001141}
1142
Geoff Lang2186c382016-10-14 10:54:54 -04001143void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001144{
Geoff Lang2186c382016-10-14 10:54:54 -04001145 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001146}
1147
Geoff Lang2186c382016-10-14 10:54:54 -04001148void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001149{
Geoff Lang2186c382016-10-14 10:54:54 -04001150 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001151}
1152
Geoff Lang2186c382016-10-14 10:54:54 -04001153void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001154{
Geoff Lang2186c382016-10-14 10:54:54 -04001155 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001156}
1157
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001158Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001160 auto framebufferIt = mFramebufferMap.find(handle);
1161 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162}
1163
Jamie Madill33dc8432013-07-26 11:55:05 -04001164FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001166 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167
Jamie Madill33dc8432013-07-26 11:55:05 -04001168 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001169 {
1170 return NULL;
1171 }
1172 else
1173 {
1174 return fence->second;
1175 }
1176}
1177
1178Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1179{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001180 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181
1182 if (query == mQueryMap.end())
1183 {
1184 return NULL;
1185 }
1186 else
1187 {
1188 if (!query->second && create)
1189 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001190 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191 query->second->addRef();
1192 }
1193 return query->second;
1194 }
1195}
1196
Geoff Lang70d0f492015-12-10 17:45:46 -05001197Query *Context::getQuery(GLuint handle) const
1198{
1199 auto iter = mQueryMap.find(handle);
1200 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1201}
1202
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001203Texture *Context::getTargetTexture(GLenum target) const
1204{
Ian Ewellbda75592016-04-18 17:25:54 -04001205 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001206 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001207}
1208
Geoff Lang76b10c92014-09-05 16:28:14 -04001209Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001211 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001212}
1213
Geoff Lang492a7e42014-11-05 13:27:06 -05001214Compiler *Context::getCompiler() const
1215{
1216 return mCompiler;
1217}
1218
Jamie Madill893ab082014-05-16 16:56:10 -04001219void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001220{
1221 switch (pname)
1222 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001223 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001224 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001226 mGLState.getBooleanv(pname, params);
1227 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229}
1230
Jamie Madill893ab082014-05-16 16:56:10 -04001231void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232{
Shannon Woods53a94a82014-06-24 15:20:36 -04001233 // Queries about context capabilities and maximums are answered by Context.
1234 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 switch (pname)
1236 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001238 params[0] = mCaps.minAliasedLineWidth;
1239 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 break;
1241 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001242 params[0] = mCaps.minAliasedPointSize;
1243 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001244 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001245 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001246 ASSERT(mExtensions.textureFilterAnisotropic);
1247 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001248 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001249 case GL_MAX_TEXTURE_LOD_BIAS:
1250 *params = mCaps.maxLODBias;
1251 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001252
1253 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1254 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1255 {
1256 ASSERT(mExtensions.pathRendering);
1257 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1258 memcpy(params, m, 16 * sizeof(GLfloat));
1259 }
1260 break;
1261
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001263 mGLState.getFloatv(pname, params);
1264 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266}
1267
Jamie Madill893ab082014-05-16 16:56:10 -04001268void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001269{
Shannon Woods53a94a82014-06-24 15:20:36 -04001270 // Queries about context capabilities and maximums are answered by Context.
1271 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001272
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001273 switch (pname)
1274 {
Geoff Lang301d1612014-07-09 10:34:37 -04001275 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1276 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1277 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001278 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1279 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1280 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001281 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1282 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1283 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001284 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001285 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1286 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1287 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001288 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001289 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001290 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1291 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1292 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1293 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001294 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1295 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001296 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1297 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001298 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001299 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1300 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1301 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1302 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001303 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001304 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001305 break;
1306 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001307 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001308 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001309 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1310 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001311 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1312 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1313 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001314 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1315 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1316 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001317 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001318 case GL_MAX_VIEWPORT_DIMS:
1319 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001320 params[0] = mCaps.maxViewportWidth;
1321 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001322 }
1323 break;
1324 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001325 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001326 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001327 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1328 *params = mResetStrategy;
1329 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001330 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001331 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001332 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001333 case GL_SHADER_BINARY_FORMATS:
1334 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1335 break;
1336 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001337 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001338 break;
1339 case GL_PROGRAM_BINARY_FORMATS:
1340 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001341 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001342 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001343 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001344 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001345
1346 // GL_KHR_debug
1347 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1348 *params = mExtensions.maxDebugMessageLength;
1349 break;
1350 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1351 *params = mExtensions.maxDebugLoggedMessages;
1352 break;
1353 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1354 *params = mExtensions.maxDebugGroupStackDepth;
1355 break;
1356 case GL_MAX_LABEL_LENGTH:
1357 *params = mExtensions.maxLabelLength;
1358 break;
1359
Ian Ewell53f59f42016-01-28 17:36:55 -05001360 // GL_EXT_disjoint_timer_query
1361 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001362 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001363 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001364 case GL_MAX_FRAMEBUFFER_WIDTH:
1365 *params = mCaps.maxFramebufferWidth;
1366 break;
1367 case GL_MAX_FRAMEBUFFER_HEIGHT:
1368 *params = mCaps.maxFramebufferHeight;
1369 break;
1370 case GL_MAX_FRAMEBUFFER_SAMPLES:
1371 *params = mCaps.maxFramebufferSamples;
1372 break;
1373 case GL_MAX_SAMPLE_MASK_WORDS:
1374 *params = mCaps.maxSampleMaskWords;
1375 break;
1376 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1377 *params = mCaps.maxColorTextureSamples;
1378 break;
1379 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1380 *params = mCaps.maxDepthTextureSamples;
1381 break;
1382 case GL_MAX_INTEGER_SAMPLES:
1383 *params = mCaps.maxIntegerSamples;
1384 break;
1385 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1386 *params = mCaps.maxVertexAttribRelativeOffset;
1387 break;
1388 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1389 *params = mCaps.maxVertexAttribBindings;
1390 break;
1391 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1392 *params = mCaps.maxVertexAttribStride;
1393 break;
1394 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1395 *params = mCaps.maxVertexAtomicCounterBuffers;
1396 break;
1397 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1398 *params = mCaps.maxVertexAtomicCounters;
1399 break;
1400 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1401 *params = mCaps.maxVertexImageUniforms;
1402 break;
1403 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1404 *params = mCaps.maxVertexShaderStorageBlocks;
1405 break;
1406 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1407 *params = mCaps.maxFragmentAtomicCounterBuffers;
1408 break;
1409 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1410 *params = mCaps.maxFragmentAtomicCounters;
1411 break;
1412 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1413 *params = mCaps.maxFragmentImageUniforms;
1414 break;
1415 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1416 *params = mCaps.maxFragmentShaderStorageBlocks;
1417 break;
1418 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1419 *params = mCaps.minProgramTextureGatherOffset;
1420 break;
1421 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1422 *params = mCaps.maxProgramTextureGatherOffset;
1423 break;
1424 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1425 *params = mCaps.maxComputeWorkGroupInvocations;
1426 break;
1427 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1428 *params = mCaps.maxComputeUniformBlocks;
1429 break;
1430 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1431 *params = mCaps.maxComputeTextureImageUnits;
1432 break;
1433 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1434 *params = mCaps.maxComputeSharedMemorySize;
1435 break;
1436 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1437 *params = mCaps.maxComputeUniformComponents;
1438 break;
1439 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1440 *params = mCaps.maxComputeAtomicCounterBuffers;
1441 break;
1442 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1443 *params = mCaps.maxComputeAtomicCounters;
1444 break;
1445 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1446 *params = mCaps.maxComputeImageUniforms;
1447 break;
1448 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1449 *params = mCaps.maxCombinedComputeUniformComponents;
1450 break;
1451 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1452 *params = mCaps.maxComputeShaderStorageBlocks;
1453 break;
1454 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1455 *params = mCaps.maxCombinedShaderOutputResources;
1456 break;
1457 case GL_MAX_UNIFORM_LOCATIONS:
1458 *params = mCaps.maxUniformLocations;
1459 break;
1460 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1461 *params = mCaps.maxAtomicCounterBufferBindings;
1462 break;
1463 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1464 *params = mCaps.maxAtomicCounterBufferSize;
1465 break;
1466 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1467 *params = mCaps.maxCombinedAtomicCounterBuffers;
1468 break;
1469 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1470 *params = mCaps.maxCombinedAtomicCounters;
1471 break;
1472 case GL_MAX_IMAGE_UNITS:
1473 *params = mCaps.maxImageUnits;
1474 break;
1475 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1476 *params = mCaps.maxCombinedImageUniforms;
1477 break;
1478 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1479 *params = mCaps.maxShaderStorageBufferBindings;
1480 break;
1481 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1482 *params = mCaps.maxCombinedShaderStorageBlocks;
1483 break;
1484 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1485 *params = mCaps.shaderStorageBufferOffsetAlignment;
1486 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001487 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001488 mGLState.getIntegerv(mState, pname, params);
1489 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001490 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001491}
1492
Jamie Madill893ab082014-05-16 16:56:10 -04001493void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001494{
Shannon Woods53a94a82014-06-24 15:20:36 -04001495 // Queries about context capabilities and maximums are answered by Context.
1496 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001497 switch (pname)
1498 {
1499 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001500 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001501 break;
1502 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001503 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001504 break;
1505 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001506 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001507 break;
1508 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001509 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001510 break;
1511 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001512 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001513 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001514
1515 // GL_EXT_disjoint_timer_query
1516 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001517 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001518 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001519
1520 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1521 *params = mCaps.maxShaderStorageBlockSize;
1522 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001524 UNREACHABLE();
1525 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001526 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001527}
1528
Geoff Lang70d0f492015-12-10 17:45:46 -05001529void Context::getPointerv(GLenum pname, void **params) const
1530{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001531 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001532}
1533
Martin Radev66fb8202016-07-28 11:45:20 +03001534void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001535{
Shannon Woods53a94a82014-06-24 15:20:36 -04001536 // Queries about context capabilities and maximums are answered by Context.
1537 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001538
1539 GLenum nativeType;
1540 unsigned int numParams;
1541 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1542 ASSERT(queryStatus);
1543
1544 if (nativeType == GL_INT)
1545 {
1546 switch (target)
1547 {
1548 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1549 ASSERT(index < 3u);
1550 *data = mCaps.maxComputeWorkGroupCount[index];
1551 break;
1552 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1553 ASSERT(index < 3u);
1554 *data = mCaps.maxComputeWorkGroupSize[index];
1555 break;
1556 default:
1557 mGLState.getIntegeri_v(target, index, data);
1558 }
1559 }
1560 else
1561 {
1562 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1563 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001564}
1565
Martin Radev66fb8202016-07-28 11:45:20 +03001566void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001567{
Shannon Woods53a94a82014-06-24 15:20:36 -04001568 // Queries about context capabilities and maximums are answered by Context.
1569 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001570
1571 GLenum nativeType;
1572 unsigned int numParams;
1573 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1574 ASSERT(queryStatus);
1575
1576 if (nativeType == GL_INT_64_ANGLEX)
1577 {
1578 mGLState.getInteger64i_v(target, index, data);
1579 }
1580 else
1581 {
1582 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1583 }
1584}
1585
1586void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1587{
1588 // Queries about context capabilities and maximums are answered by Context.
1589 // Queries about current GL state values are answered by State.
1590
1591 GLenum nativeType;
1592 unsigned int numParams;
1593 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1594 ASSERT(queryStatus);
1595
1596 if (nativeType == GL_BOOL)
1597 {
1598 mGLState.getBooleani_v(target, index, data);
1599 }
1600 else
1601 {
1602 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1603 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001604}
1605
Geoff Langf6db0982015-08-25 13:04:00 -04001606Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607{
Jamie Madill1b94d432015-08-07 13:23:23 -04001608 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001609 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001610 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001611
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001612 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001613}
1614
Geoff Langf6db0982015-08-25 13:04:00 -04001615Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1616{
1617 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001618 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001619 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001620
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001621 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001622}
1623
1624Error Context::drawElements(GLenum mode,
1625 GLsizei count,
1626 GLenum type,
1627 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001628 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629{
Jamie Madill1b94d432015-08-07 13:23:23 -04001630 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001631 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001632}
1633
1634Error Context::drawElementsInstanced(GLenum mode,
1635 GLsizei count,
1636 GLenum type,
1637 const GLvoid *indices,
1638 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001639 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001640{
1641 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001642 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1643 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001644}
1645
1646Error Context::drawRangeElements(GLenum mode,
1647 GLuint start,
1648 GLuint end,
1649 GLsizei count,
1650 GLenum type,
1651 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001652 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001653{
1654 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001655 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656}
1657
Geoff Lang129753a2015-01-09 16:52:09 -05001658Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001660 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001661}
1662
1663Error Context::finish()
1664{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001665 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001666}
1667
Austin Kinross6ee1e782015-05-29 17:05:37 -07001668void Context::insertEventMarker(GLsizei length, const char *marker)
1669{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001670 ASSERT(mImplementation);
1671 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001672}
1673
1674void Context::pushGroupMarker(GLsizei length, const char *marker)
1675{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001676 ASSERT(mImplementation);
1677 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001678}
1679
1680void Context::popGroupMarker()
1681{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001682 ASSERT(mImplementation);
1683 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001684}
1685
Geoff Langd8605522016-04-13 10:19:12 -04001686void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1687{
1688 Program *programObject = getProgram(program);
1689 ASSERT(programObject);
1690
1691 programObject->bindUniformLocation(location, name);
1692}
1693
Sami Väisänena797e062016-05-12 15:23:40 +03001694void Context::setCoverageModulation(GLenum components)
1695{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001696 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001697}
1698
Sami Väisänene45e53b2016-05-25 10:36:04 +03001699void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1700{
1701 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1702}
1703
1704void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1705{
1706 GLfloat I[16];
1707 angle::Matrix<GLfloat>::setToIdentity(I);
1708
1709 mGLState.loadPathRenderingMatrix(matrixMode, I);
1710}
1711
1712void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1713{
1714 const auto *pathObj = mResourceManager->getPath(path);
1715 if (!pathObj)
1716 return;
1717
1718 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1719 syncRendererState();
1720
1721 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1722}
1723
1724void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1725{
1726 const auto *pathObj = mResourceManager->getPath(path);
1727 if (!pathObj)
1728 return;
1729
1730 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1731 syncRendererState();
1732
1733 mImplementation->stencilStrokePath(pathObj, reference, mask);
1734}
1735
1736void Context::coverFillPath(GLuint path, GLenum coverMode)
1737{
1738 const auto *pathObj = mResourceManager->getPath(path);
1739 if (!pathObj)
1740 return;
1741
1742 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1743 syncRendererState();
1744
1745 mImplementation->coverFillPath(pathObj, coverMode);
1746}
1747
1748void Context::coverStrokePath(GLuint path, GLenum coverMode)
1749{
1750 const auto *pathObj = mResourceManager->getPath(path);
1751 if (!pathObj)
1752 return;
1753
1754 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1755 syncRendererState();
1756
1757 mImplementation->coverStrokePath(pathObj, coverMode);
1758}
1759
1760void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1761{
1762 const auto *pathObj = mResourceManager->getPath(path);
1763 if (!pathObj)
1764 return;
1765
1766 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1767 syncRendererState();
1768
1769 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1770}
1771
1772void Context::stencilThenCoverStrokePath(GLuint path,
1773 GLint reference,
1774 GLuint mask,
1775 GLenum coverMode)
1776{
1777 const auto *pathObj = mResourceManager->getPath(path);
1778 if (!pathObj)
1779 return;
1780
1781 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1782 syncRendererState();
1783
1784 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1785}
1786
Sami Väisänend59ca052016-06-21 16:10:00 +03001787void Context::coverFillPathInstanced(GLsizei numPaths,
1788 GLenum pathNameType,
1789 const void *paths,
1790 GLuint pathBase,
1791 GLenum coverMode,
1792 GLenum transformType,
1793 const GLfloat *transformValues)
1794{
1795 const auto &pathObjects =
1796 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1797
1798 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1799 syncRendererState();
1800
1801 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1802}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001803
Sami Väisänend59ca052016-06-21 16:10:00 +03001804void Context::coverStrokePathInstanced(GLsizei numPaths,
1805 GLenum pathNameType,
1806 const void *paths,
1807 GLuint pathBase,
1808 GLenum coverMode,
1809 GLenum transformType,
1810 const GLfloat *transformValues)
1811{
1812 const auto &pathObjects =
1813 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1814
1815 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1816 syncRendererState();
1817
1818 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1819 transformValues);
1820}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001821
Sami Väisänend59ca052016-06-21 16:10:00 +03001822void Context::stencilFillPathInstanced(GLsizei numPaths,
1823 GLenum pathNameType,
1824 const void *paths,
1825 GLuint pathBase,
1826 GLenum fillMode,
1827 GLuint mask,
1828 GLenum transformType,
1829 const GLfloat *transformValues)
1830{
1831 const auto &pathObjects =
1832 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1833
1834 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1835 syncRendererState();
1836
1837 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1838 transformValues);
1839}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001840
Sami Väisänend59ca052016-06-21 16:10:00 +03001841void Context::stencilStrokePathInstanced(GLsizei numPaths,
1842 GLenum pathNameType,
1843 const void *paths,
1844 GLuint pathBase,
1845 GLint reference,
1846 GLuint mask,
1847 GLenum transformType,
1848 const GLfloat *transformValues)
1849{
1850 const auto &pathObjects =
1851 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1852
1853 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1854 syncRendererState();
1855
1856 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1857 transformValues);
1858}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001859
Sami Väisänend59ca052016-06-21 16:10:00 +03001860void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1861 GLenum pathNameType,
1862 const void *paths,
1863 GLuint pathBase,
1864 GLenum fillMode,
1865 GLuint mask,
1866 GLenum coverMode,
1867 GLenum transformType,
1868 const GLfloat *transformValues)
1869{
1870 const auto &pathObjects =
1871 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1872
1873 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1874 syncRendererState();
1875
1876 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1877 transformType, transformValues);
1878}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001879
Sami Väisänend59ca052016-06-21 16:10:00 +03001880void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1881 GLenum pathNameType,
1882 const void *paths,
1883 GLuint pathBase,
1884 GLint reference,
1885 GLuint mask,
1886 GLenum coverMode,
1887 GLenum transformType,
1888 const GLfloat *transformValues)
1889{
1890 const auto &pathObjects =
1891 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1892
1893 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1894 syncRendererState();
1895
1896 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1897 transformType, transformValues);
1898}
1899
Sami Väisänen46eaa942016-06-29 10:26:37 +03001900void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1901{
1902 auto *programObject = getProgram(program);
1903
1904 programObject->bindFragmentInputLocation(location, name);
1905}
1906
1907void Context::programPathFragmentInputGen(GLuint program,
1908 GLint location,
1909 GLenum genMode,
1910 GLint components,
1911 const GLfloat *coeffs)
1912{
1913 auto *programObject = getProgram(program);
1914
1915 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1916}
1917
Jamie Madill437fa652016-05-03 15:13:24 -04001918void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001919{
Geoff Langda5777c2014-07-11 09:52:58 -04001920 if (error.isError())
1921 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001922 GLenum code = error.getCode();
1923 mErrors.insert(code);
1924 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1925 {
1926 markContextLost();
1927 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001928
1929 if (!error.getMessage().empty())
1930 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001931 auto *debug = &mGLState.getDebug();
1932 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1933 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001934 }
Geoff Langda5777c2014-07-11 09:52:58 -04001935 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936}
1937
1938// Get one of the recorded errors and clear its flag, if any.
1939// [OpenGL ES 2.0.24] section 2.5 page 13.
1940GLenum Context::getError()
1941{
Geoff Langda5777c2014-07-11 09:52:58 -04001942 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943 {
Geoff Langda5777c2014-07-11 09:52:58 -04001944 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001945 }
Geoff Langda5777c2014-07-11 09:52:58 -04001946 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001947 {
Geoff Langda5777c2014-07-11 09:52:58 -04001948 GLenum error = *mErrors.begin();
1949 mErrors.erase(mErrors.begin());
1950 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001951 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001952}
1953
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001954// NOTE: this function should not assume that this context is current!
1955void Context::markContextLost()
1956{
1957 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001958 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001959 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001960 mContextLostForced = true;
1961 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001962 mContextLost = true;
1963}
1964
1965bool Context::isContextLost()
1966{
1967 return mContextLost;
1968}
1969
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001970GLenum Context::getResetStatus()
1971{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001972 // Even if the application doesn't want to know about resets, we want to know
1973 // as it will allow us to skip all the calls.
1974 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001975 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001976 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001977 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001978 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001979 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980
1981 // EXT_robustness, section 2.6: If the reset notification behavior is
1982 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1983 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1984 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001985 }
1986
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001987 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1988 // status should be returned at least once, and GL_NO_ERROR should be returned
1989 // once the device has finished resetting.
1990 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001992 ASSERT(mResetStatus == GL_NO_ERROR);
1993 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001994
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001995 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001997 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001998 }
1999 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002000 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002001 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002002 // If markContextLost was used to mark the context lost then
2003 // assume that is not recoverable, and continue to report the
2004 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002005 mResetStatus = mImplementation->getResetStatus();
2006 }
Jamie Madill893ab082014-05-16 16:56:10 -04002007
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002008 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002009}
2010
2011bool Context::isResetNotificationEnabled()
2012{
2013 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2014}
2015
Corentin Walleze3b10e82015-05-20 11:06:25 -04002016const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002017{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002018 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002019}
2020
2021EGLenum Context::getClientType() const
2022{
2023 return mClientType;
2024}
2025
2026EGLenum Context::getRenderBuffer() const
2027{
Corentin Wallez37c39792015-08-20 14:19:46 -04002028 auto framebufferIt = mFramebufferMap.find(0);
2029 if (framebufferIt != mFramebufferMap.end())
2030 {
2031 const Framebuffer *framebuffer = framebufferIt->second;
2032 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2033
2034 ASSERT(backAttachment != nullptr);
2035 return backAttachment->getSurface()->getRenderBuffer();
2036 }
2037 else
2038 {
2039 return EGL_NONE;
2040 }
Régis Fénéon83107972015-02-05 12:57:44 +01002041}
2042
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002043VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002044{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002045 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002046 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2047 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002048 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002049 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002051 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002052 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053
2054 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002055}
2056
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002057TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002058{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002059 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002060 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2061 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002062 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002063 transformFeedback =
2064 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002065 transformFeedback->addRef();
2066 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002067 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002068
2069 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002070}
2071
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002072Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2073{
2074 // Can be called from Bind without a prior call to Gen.
2075 auto framebufferIt = mFramebufferMap.find(framebuffer);
2076 bool neverCreated = framebufferIt == mFramebufferMap.end();
2077 if (neverCreated || framebufferIt->second == nullptr)
2078 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002079 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002080 if (neverCreated)
2081 {
2082 mFramebufferHandleAllocator.reserve(framebuffer);
2083 mFramebufferMap[framebuffer] = newFBO;
2084 return newFBO;
2085 }
2086
2087 framebufferIt->second = newFBO;
2088 }
2089
2090 return framebufferIt->second;
2091}
2092
Geoff Langf41a7152016-09-19 15:11:17 -04002093bool Context::isTextureGenerated(GLuint texture) const
2094{
2095 return mResourceManager->isTextureGenerated(texture);
2096}
2097
2098bool Context::isBufferGenerated(GLuint buffer) const
2099{
2100 return mResourceManager->isBufferGenerated(buffer);
2101}
2102
2103bool Context::isRenderbufferGenerated(GLuint renderbuffer) const
2104{
2105 return mResourceManager->isRenderbufferGenerated(renderbuffer);
2106}
2107
2108bool Context::isFramebufferGenerated(GLuint framebuffer) const
2109{
2110 ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end());
2111 return mFramebufferMap.find(framebuffer) != mFramebufferMap.end();
2112}
2113
Geoff Lang36167ab2015-12-07 10:27:14 -05002114bool Context::isVertexArrayGenerated(GLuint vertexArray)
2115{
Geoff Langf41a7152016-09-19 15:11:17 -04002116 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002117 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2118}
2119
2120bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2121{
Geoff Langf41a7152016-09-19 15:11:17 -04002122 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002123 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2124}
2125
Shannon Woods53a94a82014-06-24 15:20:36 -04002126void Context::detachTexture(GLuint texture)
2127{
2128 // Simple pass-through to State's detachTexture method, as textures do not require
2129 // allocation map management either here or in the resource manager at detach time.
2130 // Zero textures are held by the Context, and we don't attempt to request them from
2131 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002133}
2134
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002135void Context::detachBuffer(GLuint buffer)
2136{
Yuly Novikov5807a532015-12-03 13:01:22 -05002137 // Simple pass-through to State's detachBuffer method, since
2138 // only buffer attachments to container objects that are bound to the current context
2139 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002140
Yuly Novikov5807a532015-12-03 13:01:22 -05002141 // [OpenGL ES 3.2] section 5.1.2 page 45:
2142 // Attachments to unbound container objects, such as
2143 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2144 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002146}
2147
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148void Context::detachFramebuffer(GLuint framebuffer)
2149{
Shannon Woods53a94a82014-06-24 15:20:36 -04002150 // Framebuffer detachment is handled by Context, because 0 is a valid
2151 // Framebuffer object, and a pointer to it must be passed from Context
2152 // to State at binding time.
2153
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002154 // [OpenGL ES 2.0.24] section 4.4 page 107:
2155 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2156 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2157
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002158 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159 {
2160 bindReadFramebuffer(0);
2161 }
2162
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002163 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002164 {
2165 bindDrawFramebuffer(0);
2166 }
2167}
2168
2169void Context::detachRenderbuffer(GLuint renderbuffer)
2170{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002171 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002172}
2173
Jamie Madill57a89722013-07-02 11:57:03 -04002174void Context::detachVertexArray(GLuint vertexArray)
2175{
Jamie Madill77a72f62015-04-14 11:18:32 -04002176 // Vertex array detachment is handled by Context, because 0 is a valid
2177 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002178 // binding time.
2179
Jamie Madill57a89722013-07-02 11:57:03 -04002180 // [OpenGL ES 3.0.2] section 2.10 page 43:
2181 // If a vertex array object that is currently bound is deleted, the binding
2182 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002183 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002184 {
2185 bindVertexArray(0);
2186 }
2187}
2188
Geoff Langc8058452014-02-03 12:04:11 -05002189void Context::detachTransformFeedback(GLuint transformFeedback)
2190{
Corentin Walleza2257da2016-04-19 16:43:12 -04002191 // Transform feedback detachment is handled by Context, because 0 is a valid
2192 // transform feedback, and a pointer to it must be passed from Context to State at
2193 // binding time.
2194
2195 // The OpenGL specification doesn't mention what should happen when the currently bound
2196 // transform feedback object is deleted. Since it is a container object, we treat it like
2197 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002198 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002199 {
2200 bindTransformFeedback(0);
2201 }
Geoff Langc8058452014-02-03 12:04:11 -05002202}
2203
Jamie Madilldc356042013-07-19 16:36:57 -04002204void Context::detachSampler(GLuint sampler)
2205{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002206 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002207}
2208
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002209void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2210{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002211 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002212}
2213
Jamie Madille29d1672013-07-19 16:36:57 -04002214void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2215{
Geoff Langc1984ed2016-10-07 12:41:00 -04002216 Sampler *samplerObject =
2217 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2218 SetSamplerParameteri(samplerObject, pname, param);
2219}
Jamie Madille29d1672013-07-19 16:36:57 -04002220
Geoff Langc1984ed2016-10-07 12:41:00 -04002221void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2222{
2223 Sampler *samplerObject =
2224 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2225 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002226}
2227
2228void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2229{
Geoff Langc1984ed2016-10-07 12:41:00 -04002230 Sampler *samplerObject =
2231 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2232 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002233}
2234
Geoff Langc1984ed2016-10-07 12:41:00 -04002235void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002236{
Geoff Langc1984ed2016-10-07 12:41:00 -04002237 Sampler *samplerObject =
2238 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2239 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002240}
2241
Geoff Langc1984ed2016-10-07 12:41:00 -04002242void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002243{
Geoff Langc1984ed2016-10-07 12:41:00 -04002244 const Sampler *samplerObject =
2245 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2246 QuerySamplerParameteriv(samplerObject, pname, params);
2247}
Jamie Madill9675b802013-07-19 16:36:59 -04002248
Geoff Langc1984ed2016-10-07 12:41:00 -04002249void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2250{
2251 const Sampler *samplerObject =
2252 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
2253 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002254}
2255
Olli Etuahof0fee072016-03-30 15:11:58 +03002256void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2257{
2258 gl::Program *programObject = getProgram(program);
2259 ASSERT(programObject != nullptr);
2260
2261 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2262 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2263}
2264
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002265void Context::initRendererString()
2266{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002267 std::ostringstream rendererString;
2268 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002269 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002270 rendererString << ")";
2271
Geoff Langcec35902014-04-16 10:52:36 -04002272 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002273}
2274
Geoff Langc287ea62016-09-16 14:46:51 -04002275const char *Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002277 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002278}
2279
Geoff Langcec35902014-04-16 10:52:36 -04002280void Context::initExtensionStrings()
2281{
Geoff Langc287ea62016-09-16 14:46:51 -04002282 for (const auto &extensionString : mExtensions.getStrings())
2283 {
2284 mExtensionStrings.push_back(MakeStaticString(extensionString));
2285 }
Geoff Langcec35902014-04-16 10:52:36 -04002286
Geoff Langc0b9ef42014-07-02 10:02:37 -04002287 std::ostringstream combinedStringStream;
Geoff Langc287ea62016-09-16 14:46:51 -04002288 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(),
2289 std::ostream_iterator<const char *>(combinedStringStream, " "));
2290 mExtensionString = MakeStaticString(combinedStringStream.str());
Geoff Langcec35902014-04-16 10:52:36 -04002291}
2292
Geoff Langc287ea62016-09-16 14:46:51 -04002293const char *Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002294{
2295 return mExtensionString;
2296}
2297
Geoff Langc287ea62016-09-16 14:46:51 -04002298const char *Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002299{
2300 return mExtensionStrings[idx];
2301}
2302
2303size_t Context::getExtensionStringCount() const
2304{
2305 return mExtensionStrings.size();
2306}
2307
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002308void Context::beginTransformFeedback(GLenum primitiveMode)
2309{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002310 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002311 ASSERT(transformFeedback != nullptr);
2312 ASSERT(!transformFeedback->isPaused());
2313
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002314 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002315}
2316
2317bool Context::hasActiveTransformFeedback(GLuint program) const
2318{
2319 for (auto pair : mTransformFeedbackMap)
2320 {
2321 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2322 {
2323 return true;
2324 }
2325 }
2326 return false;
2327}
2328
Geoff Langc287ea62016-09-16 14:46:51 -04002329void Context::initCaps(bool webGLContext)
Geoff Lang493daf52014-07-03 13:38:44 -04002330{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002331 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002332
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002333 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002334
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002335 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002336
Geoff Langeb66a6e2016-10-31 13:06:12 -04002337 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002338 {
2339 // Disable ES3+ extensions
2340 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002341 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002342 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002343 }
2344
Geoff Langeb66a6e2016-10-31 13:06:12 -04002345 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002346 {
2347 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2348 //mExtensions.sRGB = false;
2349 }
2350
Jamie Madill00ed7a12016-05-19 13:13:38 -04002351 // Some extensions are always available because they are implemented in the GL layer.
2352 mExtensions.bindUniformLocation = true;
2353 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002354 mExtensions.bindGeneratesResource = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002355
2356 // Enable the no error extension if the context was created with the flag.
2357 mExtensions.noError = mSkipValidation;
2358
Geoff Lang70d0f492015-12-10 17:45:46 -05002359 // Explicitly enable GL_KHR_debug
2360 mExtensions.debug = true;
2361 mExtensions.maxDebugMessageLength = 1024;
2362 mExtensions.maxDebugLoggedMessages = 1024;
2363 mExtensions.maxDebugGroupStackDepth = 1024;
2364 mExtensions.maxLabelLength = 1024;
2365
Geoff Langff5b2d52016-09-07 11:32:23 -04002366 // Explicitly enable GL_ANGLE_robust_client_memory
2367 mExtensions.robustClientMemory = true;
2368
Geoff Lang301d1612014-07-09 10:34:37 -04002369 // Apply implementation limits
2370 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002371 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2372 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2373
2374 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002375
Geoff Langc287ea62016-09-16 14:46:51 -04002376 // WebGL compatibility
2377 mExtensions.webglCompatibility = webGLContext;
2378 for (const auto &extensionInfo : GetExtensionInfoMap())
2379 {
2380 // If this context is for WebGL, disable all enableable extensions
2381 if (webGLContext && extensionInfo.second.Enableable)
2382 {
2383 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2384 }
2385 }
2386
2387 // Generate texture caps
2388 updateCaps();
2389}
2390
2391void Context::updateCaps()
2392{
Geoff Lang900013c2014-07-07 11:32:19 -04002393 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002394 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002395
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002396 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002397 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2398 {
2399 GLenum format = i->first;
2400 TextureCaps formatCaps = i->second;
2401
Geoff Lang5d601382014-07-22 15:14:06 -04002402 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002403
Geoff Lang0d8b7242015-09-09 14:56:53 -04002404 // Update the format caps based on the client version and extensions.
2405 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2406 // ES3.
2407 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002408 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002409 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002410 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002411 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002412 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002413
2414 // OpenGL ES does not support multisampling with integer formats
2415 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002416 {
Geoff Langd87878e2014-09-19 15:42:59 -04002417 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002418 }
Geoff Langd87878e2014-09-19 15:42:59 -04002419
2420 if (formatCaps.texturable && formatInfo.compressed)
2421 {
2422 mCaps.compressedTextureFormats.push_back(format);
2423 }
2424
2425 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002426 }
2427}
2428
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002429void Context::initWorkarounds()
2430{
2431 // Lose the context upon out of memory error if the application is
2432 // expecting to watch for those events.
2433 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2434}
2435
Jamie Madill1b94d432015-08-07 13:23:23 -04002436void Context::syncRendererState()
2437{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002438 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2439 mImplementation->syncState(mGLState, dirtyBits);
2440 mGLState.clearDirtyBits();
2441 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002442}
2443
Jamie Madillad9f24e2016-02-12 09:27:24 -05002444void Context::syncRendererState(const State::DirtyBits &bitMask,
2445 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002446{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002447 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2448 mImplementation->syncState(mGLState, dirtyBits);
2449 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002450
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002451 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002452}
Jamie Madillc29968b2016-01-20 11:17:23 -05002453
2454void Context::blitFramebuffer(GLint srcX0,
2455 GLint srcY0,
2456 GLint srcX1,
2457 GLint srcY1,
2458 GLint dstX0,
2459 GLint dstY0,
2460 GLint dstX1,
2461 GLint dstY1,
2462 GLbitfield mask,
2463 GLenum filter)
2464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002465 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002466 ASSERT(drawFramebuffer);
2467
2468 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2469 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2470
Jamie Madillad9f24e2016-02-12 09:27:24 -05002471 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002472
Jamie Madill8415b5f2016-04-26 13:41:39 -04002473 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002474}
Jamie Madillc29968b2016-01-20 11:17:23 -05002475
2476void Context::clear(GLbitfield mask)
2477{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002478 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002479 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002480}
2481
2482void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2483{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002484 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002485 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2486 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002487}
2488
2489void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2490{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002491 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002492 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2493 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002494}
2495
2496void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2497{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002498 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002499 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2500 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002501}
2502
2503void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2504{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002505 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002506 ASSERT(framebufferObject);
2507
2508 // If a buffer is not present, the clear has no effect
2509 if (framebufferObject->getDepthbuffer() == nullptr &&
2510 framebufferObject->getStencilbuffer() == nullptr)
2511 {
2512 return;
2513 }
2514
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002516 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2517 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002518}
2519
2520void Context::readPixels(GLint x,
2521 GLint y,
2522 GLsizei width,
2523 GLsizei height,
2524 GLenum format,
2525 GLenum type,
2526 GLvoid *pixels)
2527{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002528 if (width == 0 || height == 0)
2529 {
2530 return;
2531 }
2532
Jamie Madillad9f24e2016-02-12 09:27:24 -05002533 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002534
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002535 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002536 ASSERT(framebufferObject);
2537
2538 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002539 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002540}
2541
2542void Context::copyTexImage2D(GLenum target,
2543 GLint level,
2544 GLenum internalformat,
2545 GLint x,
2546 GLint y,
2547 GLsizei width,
2548 GLsizei height,
2549 GLint border)
2550{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002551 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002552 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002553
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 Rectangle sourceArea(x, y, width, height);
2555
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002556 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002557 Texture *texture =
2558 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002559 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002560}
2561
2562void Context::copyTexSubImage2D(GLenum target,
2563 GLint level,
2564 GLint xoffset,
2565 GLint yoffset,
2566 GLint x,
2567 GLint y,
2568 GLsizei width,
2569 GLsizei height)
2570{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002571 if (width == 0 || height == 0)
2572 {
2573 return;
2574 }
2575
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002576 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002577 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002578
Jamie Madillc29968b2016-01-20 11:17:23 -05002579 Offset destOffset(xoffset, yoffset, 0);
2580 Rectangle sourceArea(x, y, width, height);
2581
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002582 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002583 Texture *texture =
2584 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002585 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002586}
2587
2588void Context::copyTexSubImage3D(GLenum target,
2589 GLint level,
2590 GLint xoffset,
2591 GLint yoffset,
2592 GLint zoffset,
2593 GLint x,
2594 GLint y,
2595 GLsizei width,
2596 GLsizei height)
2597{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002598 if (width == 0 || height == 0)
2599 {
2600 return;
2601 }
2602
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002603 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002604 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002605
Jamie Madillc29968b2016-01-20 11:17:23 -05002606 Offset destOffset(xoffset, yoffset, zoffset);
2607 Rectangle sourceArea(x, y, width, height);
2608
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002609 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002611 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002612}
2613
2614void Context::framebufferTexture2D(GLenum target,
2615 GLenum attachment,
2616 GLenum textarget,
2617 GLuint texture,
2618 GLint level)
2619{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002620 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002621 ASSERT(framebuffer);
2622
2623 if (texture != 0)
2624 {
2625 Texture *textureObj = getTexture(texture);
2626
2627 ImageIndex index = ImageIndex::MakeInvalid();
2628
2629 if (textarget == GL_TEXTURE_2D)
2630 {
2631 index = ImageIndex::Make2D(level);
2632 }
2633 else
2634 {
2635 ASSERT(IsCubeMapTextureTarget(textarget));
2636 index = ImageIndex::MakeCube(textarget, level);
2637 }
2638
2639 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2640 }
2641 else
2642 {
2643 framebuffer->resetAttachment(attachment);
2644 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002645
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002646 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002647}
2648
2649void Context::framebufferRenderbuffer(GLenum target,
2650 GLenum attachment,
2651 GLenum renderbuffertarget,
2652 GLuint renderbuffer)
2653{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002654 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002655 ASSERT(framebuffer);
2656
2657 if (renderbuffer != 0)
2658 {
2659 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2660 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2661 renderbufferObject);
2662 }
2663 else
2664 {
2665 framebuffer->resetAttachment(attachment);
2666 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002667
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002668 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002669}
2670
2671void Context::framebufferTextureLayer(GLenum target,
2672 GLenum attachment,
2673 GLuint texture,
2674 GLint level,
2675 GLint layer)
2676{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002677 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002678 ASSERT(framebuffer);
2679
2680 if (texture != 0)
2681 {
2682 Texture *textureObject = getTexture(texture);
2683
2684 ImageIndex index = ImageIndex::MakeInvalid();
2685
2686 if (textureObject->getTarget() == GL_TEXTURE_3D)
2687 {
2688 index = ImageIndex::Make3D(level, layer);
2689 }
2690 else
2691 {
2692 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2693 index = ImageIndex::Make2DArray(level, layer);
2694 }
2695
2696 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2697 }
2698 else
2699 {
2700 framebuffer->resetAttachment(attachment);
2701 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002702
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002703 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002704}
2705
2706void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2707{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002708 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002709 ASSERT(framebuffer);
2710 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002711 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002712}
2713
2714void Context::readBuffer(GLenum mode)
2715{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002716 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002717 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002718 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002719}
2720
2721void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2722{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002723 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002724 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002725
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002727 ASSERT(framebuffer);
2728
2729 // The specification isn't clear what should be done when the framebuffer isn't complete.
2730 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002731 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002732}
2733
2734void Context::invalidateFramebuffer(GLenum target,
2735 GLsizei numAttachments,
2736 const GLenum *attachments)
2737{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002738 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002739 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002740
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002742 ASSERT(framebuffer);
2743
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002744 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002745 {
Jamie Madill437fa652016-05-03 15:13:24 -04002746 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002747 }
Jamie Madill437fa652016-05-03 15:13:24 -04002748
2749 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002750}
2751
2752void Context::invalidateSubFramebuffer(GLenum target,
2753 GLsizei numAttachments,
2754 const GLenum *attachments,
2755 GLint x,
2756 GLint y,
2757 GLsizei width,
2758 GLsizei height)
2759{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002760 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002761 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002762
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002764 ASSERT(framebuffer);
2765
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002767 {
Jamie Madill437fa652016-05-03 15:13:24 -04002768 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002769 }
Jamie Madill437fa652016-05-03 15:13:24 -04002770
2771 Rectangle area(x, y, width, height);
2772 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002773}
2774
Jamie Madill73a84962016-02-12 09:27:23 -05002775void Context::texImage2D(GLenum target,
2776 GLint level,
2777 GLint internalformat,
2778 GLsizei width,
2779 GLsizei height,
2780 GLint border,
2781 GLenum format,
2782 GLenum type,
2783 const GLvoid *pixels)
2784{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002785 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002786
2787 Extents size(width, height, 1);
2788 Texture *texture =
2789 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002790 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002791 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002792}
2793
2794void Context::texImage3D(GLenum target,
2795 GLint level,
2796 GLint internalformat,
2797 GLsizei width,
2798 GLsizei height,
2799 GLsizei depth,
2800 GLint border,
2801 GLenum format,
2802 GLenum type,
2803 const GLvoid *pixels)
2804{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002805 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002806
2807 Extents size(width, height, depth);
2808 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002810 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002811}
2812
2813void Context::texSubImage2D(GLenum target,
2814 GLint level,
2815 GLint xoffset,
2816 GLint yoffset,
2817 GLsizei width,
2818 GLsizei height,
2819 GLenum format,
2820 GLenum type,
2821 const GLvoid *pixels)
2822{
2823 // Zero sized uploads are valid but no-ops
2824 if (width == 0 || height == 0)
2825 {
2826 return;
2827 }
2828
Jamie Madillad9f24e2016-02-12 09:27:24 -05002829 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002830
2831 Box area(xoffset, yoffset, 0, width, height, 1);
2832 Texture *texture =
2833 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002834 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002835 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002836}
2837
2838void Context::texSubImage3D(GLenum target,
2839 GLint level,
2840 GLint xoffset,
2841 GLint yoffset,
2842 GLint zoffset,
2843 GLsizei width,
2844 GLsizei height,
2845 GLsizei depth,
2846 GLenum format,
2847 GLenum type,
2848 const GLvoid *pixels)
2849{
2850 // Zero sized uploads are valid but no-ops
2851 if (width == 0 || height == 0 || depth == 0)
2852 {
2853 return;
2854 }
2855
Jamie Madillad9f24e2016-02-12 09:27:24 -05002856 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002857
2858 Box area(xoffset, yoffset, zoffset, width, height, depth);
2859 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002860 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002861 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002862}
2863
2864void Context::compressedTexImage2D(GLenum target,
2865 GLint level,
2866 GLenum internalformat,
2867 GLsizei width,
2868 GLsizei height,
2869 GLint border,
2870 GLsizei imageSize,
2871 const GLvoid *data)
2872{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002873 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002874
2875 Extents size(width, height, 1);
2876 Texture *texture =
2877 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002878 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2879 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002880 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002881}
2882
2883void Context::compressedTexImage3D(GLenum target,
2884 GLint level,
2885 GLenum internalformat,
2886 GLsizei width,
2887 GLsizei height,
2888 GLsizei depth,
2889 GLint border,
2890 GLsizei imageSize,
2891 const GLvoid *data)
2892{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002893 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002894
2895 Extents size(width, height, depth);
2896 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002897 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2898 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002899 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002900}
2901
2902void Context::compressedTexSubImage2D(GLenum target,
2903 GLint level,
2904 GLint xoffset,
2905 GLint yoffset,
2906 GLsizei width,
2907 GLsizei height,
2908 GLenum format,
2909 GLsizei imageSize,
2910 const GLvoid *data)
2911{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002912 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002913
2914 Box area(xoffset, yoffset, 0, width, height, 1);
2915 Texture *texture =
2916 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002917 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2918 format, imageSize,
2919 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002920}
2921
2922void Context::compressedTexSubImage3D(GLenum target,
2923 GLint level,
2924 GLint xoffset,
2925 GLint yoffset,
2926 GLint zoffset,
2927 GLsizei width,
2928 GLsizei height,
2929 GLsizei depth,
2930 GLenum format,
2931 GLsizei imageSize,
2932 const GLvoid *data)
2933{
2934 // Zero sized uploads are valid but no-ops
2935 if (width == 0 || height == 0)
2936 {
2937 return;
2938 }
2939
Jamie Madillad9f24e2016-02-12 09:27:24 -05002940 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002941
2942 Box area(xoffset, yoffset, zoffset, width, height, depth);
2943 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002944 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2945 format, imageSize,
2946 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002947}
2948
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002949void Context::generateMipmap(GLenum target)
2950{
2951 Texture *texture = getTargetTexture(target);
2952 handleError(texture->generateMipmap());
2953}
2954
Geoff Langc287ea62016-09-16 14:46:51 -04002955GLboolean Context::enableExtension(const char *name)
2956{
2957 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2958 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2959 const auto &extension = extensionInfos.at(name);
2960 ASSERT(extension.Enableable);
2961
2962 if (mExtensions.*(extension.ExtensionsMember))
2963 {
2964 // Extension already enabled
2965 return GL_TRUE;
2966 }
2967
2968 const auto &nativeExtensions = mImplementation->getNativeExtensions();
2969 if (!(nativeExtensions.*(extension.ExtensionsMember)))
2970 {
2971 // Underlying implementation does not support this valid extension
2972 return GL_FALSE;
2973 }
2974
2975 mExtensions.*(extension.ExtensionsMember) = true;
2976 updateCaps();
2977 initExtensionStrings();
2978 return GL_TRUE;
2979}
2980
Geoff Lang97073d12016-04-20 10:42:34 -07002981void Context::copyTextureCHROMIUM(GLuint sourceId,
2982 GLuint destId,
2983 GLint internalFormat,
2984 GLenum destType,
2985 GLboolean unpackFlipY,
2986 GLboolean unpackPremultiplyAlpha,
2987 GLboolean unpackUnmultiplyAlpha)
2988{
2989 syncStateForTexImage();
2990
2991 gl::Texture *sourceTexture = getTexture(sourceId);
2992 gl::Texture *destTexture = getTexture(destId);
2993 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2994 unpackPremultiplyAlpha == GL_TRUE,
2995 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2996}
2997
2998void Context::copySubTextureCHROMIUM(GLuint sourceId,
2999 GLuint destId,
3000 GLint xoffset,
3001 GLint yoffset,
3002 GLint x,
3003 GLint y,
3004 GLsizei width,
3005 GLsizei height,
3006 GLboolean unpackFlipY,
3007 GLboolean unpackPremultiplyAlpha,
3008 GLboolean unpackUnmultiplyAlpha)
3009{
3010 // Zero sized copies are valid but no-ops
3011 if (width == 0 || height == 0)
3012 {
3013 return;
3014 }
3015
3016 syncStateForTexImage();
3017
3018 gl::Texture *sourceTexture = getTexture(sourceId);
3019 gl::Texture *destTexture = getTexture(destId);
3020 Offset offset(xoffset, yoffset, 0);
3021 Rectangle area(x, y, width, height);
3022 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
3023 unpackPremultiplyAlpha == GL_TRUE,
3024 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3025}
3026
Geoff Lang47110bf2016-04-20 11:13:22 -07003027void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3028{
3029 syncStateForTexImage();
3030
3031 gl::Texture *sourceTexture = getTexture(sourceId);
3032 gl::Texture *destTexture = getTexture(destId);
3033 handleError(destTexture->copyCompressedTexture(sourceTexture));
3034}
3035
Geoff Lang496c02d2016-10-20 11:38:11 -07003036void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003037{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003038 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003039 ASSERT(buffer);
3040
Geoff Lang496c02d2016-10-20 11:38:11 -07003041 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003042}
3043
3044GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3045{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003046 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003047 ASSERT(buffer);
3048
3049 Error error = buffer->map(access);
3050 if (error.isError())
3051 {
Jamie Madill437fa652016-05-03 15:13:24 -04003052 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003053 return nullptr;
3054 }
3055
3056 return buffer->getMapPointer();
3057}
3058
3059GLboolean Context::unmapBuffer(GLenum target)
3060{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003061 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003062 ASSERT(buffer);
3063
3064 GLboolean result;
3065 Error error = buffer->unmap(&result);
3066 if (error.isError())
3067 {
Jamie Madill437fa652016-05-03 15:13:24 -04003068 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003069 return GL_FALSE;
3070 }
3071
3072 return result;
3073}
3074
3075GLvoid *Context::mapBufferRange(GLenum target,
3076 GLintptr offset,
3077 GLsizeiptr length,
3078 GLbitfield access)
3079{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003080 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003081 ASSERT(buffer);
3082
3083 Error error = buffer->mapRange(offset, length, access);
3084 if (error.isError())
3085 {
Jamie Madill437fa652016-05-03 15:13:24 -04003086 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003087 return nullptr;
3088 }
3089
3090 return buffer->getMapPointer();
3091}
3092
3093void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3094{
3095 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3096}
3097
Jamie Madillad9f24e2016-02-12 09:27:24 -05003098void Context::syncStateForReadPixels()
3099{
3100 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3101}
3102
3103void Context::syncStateForTexImage()
3104{
3105 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3106}
3107
3108void Context::syncStateForClear()
3109{
3110 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3111}
3112
3113void Context::syncStateForBlit()
3114{
3115 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3116}
3117
Jamie Madillc20ab272016-06-09 07:20:46 -07003118void Context::activeTexture(GLenum texture)
3119{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003120 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003121}
3122
3123void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3124{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003125 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003126}
3127
3128void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3129{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003130 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003131}
3132
3133void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003135 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003136}
3137
3138void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3139{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003140 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003141}
3142
3143void Context::clearDepthf(GLclampf depth)
3144{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003145 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003146}
3147
3148void Context::clearStencil(GLint s)
3149{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003150 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003151}
3152
3153void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3154{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003155 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003156}
3157
3158void Context::cullFace(GLenum mode)
3159{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003160 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003161}
3162
3163void Context::depthFunc(GLenum func)
3164{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003165 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003166}
3167
3168void Context::depthMask(GLboolean flag)
3169{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003170 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003171}
3172
3173void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3174{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003175 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003176}
3177
3178void Context::disable(GLenum cap)
3179{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003180 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003181}
3182
3183void Context::disableVertexAttribArray(GLuint index)
3184{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003185 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003186}
3187
3188void Context::enable(GLenum cap)
3189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003190 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003191}
3192
3193void Context::enableVertexAttribArray(GLuint index)
3194{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003195 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003196}
3197
3198void Context::frontFace(GLenum mode)
3199{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003200 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003201}
3202
3203void Context::hint(GLenum target, GLenum mode)
3204{
3205 switch (target)
3206 {
3207 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209 break;
3210
3211 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003212 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003213 break;
3214
3215 default:
3216 UNREACHABLE();
3217 return;
3218 }
3219}
3220
3221void Context::lineWidth(GLfloat width)
3222{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224}
3225
3226void Context::pixelStorei(GLenum pname, GLint param)
3227{
3228 switch (pname)
3229 {
3230 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003231 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003232 break;
3233
3234 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003235 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003236 break;
3237
3238 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240 break;
3241
3242 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003243 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245 break;
3246
3247 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003248 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250 break;
3251
3252 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003253 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255 break;
3256
3257 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003258 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003259 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003260 break;
3261
3262 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003263 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265 break;
3266
3267 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003268 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003270 break;
3271
3272 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003273 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003275 break;
3276
3277 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003278 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280 break;
3281
3282 default:
3283 UNREACHABLE();
3284 return;
3285 }
3286}
3287
3288void Context::polygonOffset(GLfloat factor, GLfloat units)
3289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003290 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003291}
3292
3293void Context::sampleCoverage(GLclampf value, GLboolean invert)
3294{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296}
3297
3298void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3299{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003300 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003301}
3302
3303void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3304{
3305 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3306 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308 }
3309
3310 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3311 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003312 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003313 }
3314}
3315
3316void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3317{
3318 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3319 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003320 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003321 }
3322
3323 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3324 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326 }
3327}
3328
3329void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3330{
3331 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3332 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 }
3335
3336 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3337 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003339 }
3340}
3341
3342void Context::vertexAttrib1f(GLuint index, GLfloat x)
3343{
3344 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003345 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003346}
3347
3348void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3349{
3350 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003351 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003352}
3353
3354void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3355{
3356 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003357 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003358}
3359
3360void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3361{
3362 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003363 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003364}
3365
3366void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3367{
3368 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3373{
3374 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003375 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003376}
3377
3378void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3379{
3380 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003381 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003382}
3383
3384void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387}
3388
3389void Context::vertexAttribPointer(GLuint index,
3390 GLint size,
3391 GLenum type,
3392 GLboolean normalized,
3393 GLsizei stride,
3394 const GLvoid *ptr)
3395{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003396 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3397 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003398}
3399
3400void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3401{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003402 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003403}
3404
3405void Context::vertexAttribIPointer(GLuint index,
3406 GLint size,
3407 GLenum type,
3408 GLsizei stride,
3409 const GLvoid *pointer)
3410{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003411 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3412 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003413}
3414
3415void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3416{
3417 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003419}
3420
3421void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3422{
3423 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3428{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003429 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003430}
3431
3432void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003434 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003435}
3436
3437void Context::debugMessageControl(GLenum source,
3438 GLenum type,
3439 GLenum severity,
3440 GLsizei count,
3441 const GLuint *ids,
3442 GLboolean enabled)
3443{
3444 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003445 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3446 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003447}
3448
3449void Context::debugMessageInsert(GLenum source,
3450 GLenum type,
3451 GLuint id,
3452 GLenum severity,
3453 GLsizei length,
3454 const GLchar *buf)
3455{
3456 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003457 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003458}
3459
3460void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3461{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003462 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003463}
3464
3465GLuint Context::getDebugMessageLog(GLuint count,
3466 GLsizei bufSize,
3467 GLenum *sources,
3468 GLenum *types,
3469 GLuint *ids,
3470 GLenum *severities,
3471 GLsizei *lengths,
3472 GLchar *messageLog)
3473{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003474 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3475 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003476}
3477
3478void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3479{
3480 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::popDebugGroup()
3485{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003486 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003487}
3488
Jamie Madill29639852016-09-02 15:00:09 -04003489void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3490{
3491 Buffer *buffer = mGLState.getTargetBuffer(target);
3492 ASSERT(buffer);
3493 handleError(buffer->bufferData(target, data, size, usage));
3494}
3495
3496void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3497{
3498 if (data == nullptr)
3499 {
3500 return;
3501 }
3502
3503 Buffer *buffer = mGLState.getTargetBuffer(target);
3504 ASSERT(buffer);
3505 handleError(buffer->bufferSubData(target, data, size, offset));
3506}
3507
Jamie Madillef300b12016-10-07 15:12:09 -04003508void Context::attachShader(GLuint program, GLuint shader)
3509{
3510 auto programObject = mResourceManager->getProgram(program);
3511 auto shaderObject = mResourceManager->getShader(shader);
3512 ASSERT(programObject && shaderObject);
3513 programObject->attachShader(shaderObject);
3514}
3515
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003516const Workarounds &Context::getWorkarounds() const
3517{
3518 return mWorkarounds;
3519}
3520
Jamie Madillc29968b2016-01-20 11:17:23 -05003521} // namespace gl