blob: c79f3b7b703e3b285eb13afb1617687cabed28b0 [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"
Jamie Madill437fa652016-05-03 15:13:24 -040038#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040039#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030040#include "libANGLE/queryconversions.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000041
Geoff Langf6db0982015-08-25 13:04:00 -040042namespace
43{
44
Ian Ewell3ffd78b2016-01-22 16:09:42 -050045template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030046std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
47 GLsizei numPaths,
48 const void *paths,
49 GLuint pathBase)
50{
51 std::vector<gl::Path *> ret;
52 ret.reserve(numPaths);
53
54 const auto *nameArray = static_cast<const T *>(paths);
55
56 for (GLsizei i = 0; i < numPaths; ++i)
57 {
58 const GLuint pathName = nameArray[i] + pathBase;
59
60 ret.push_back(resourceManager.getPath(pathName));
61 }
62
63 return ret;
64}
65
66std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
67 GLsizei numPaths,
68 GLenum pathNameType,
69 const void *paths,
70 GLuint pathBase)
71{
72 switch (pathNameType)
73 {
74 case GL_UNSIGNED_BYTE:
75 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
76
77 case GL_BYTE:
78 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
79
80 case GL_UNSIGNED_SHORT:
81 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
82
83 case GL_SHORT:
84 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
85
86 case GL_UNSIGNED_INT:
87 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
88
89 case GL_INT:
90 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
91 }
92
93 UNREACHABLE();
94 return std::vector<gl::Path *>();
95}
96
97template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050098gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
99{
100 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
101 ASSERT(queryObject != nullptr);
102
103 switch (pname)
104 {
105 case GL_QUERY_RESULT_EXT:
106 return queryObject->getResult(params);
107 case GL_QUERY_RESULT_AVAILABLE_EXT:
108 {
109 bool available;
110 gl::Error error = queryObject->isResultAvailable(&available);
111 if (!error.isError())
112 {
113 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
114 }
115 return error;
116 }
117 default:
118 UNREACHABLE();
119 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
120 }
121}
122
Geoff Langf6db0982015-08-25 13:04:00 -0400123void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
124{
Geoff Lang1a683462015-09-29 15:09:59 -0400125 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400126 {
127 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
128 tfBufferIndex++)
129 {
130 const OffsetBindingPointer<gl::Buffer> &buffer =
131 transformFeedback->getIndexedBuffer(tfBufferIndex);
132 if (buffer.get() != nullptr)
133 {
134 buffer->onTransformFeedback();
135 }
136 }
137 }
138}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500139
140// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300141EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400143 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500144}
145
Martin Radev1be913c2016-07-11 17:59:16 +0300146EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
147{
148 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
149}
150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151GLenum GetResetStrategy(const egl::AttributeMap &attribs)
152{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400153 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
154 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 switch (attrib)
156 {
157 case EGL_NO_RESET_NOTIFICATION:
158 return GL_NO_RESET_NOTIFICATION_EXT;
159 case EGL_LOSE_CONTEXT_ON_RESET:
160 return GL_LOSE_CONTEXT_ON_RESET_EXT;
161 default:
162 UNREACHABLE();
163 return GL_NONE;
164 }
165}
166
167bool GetRobustAccess(const egl::AttributeMap &attribs)
168{
169 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
170}
171
172bool GetDebug(const egl::AttributeMap &attribs)
173{
174 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
175}
176
177bool GetNoError(const egl::AttributeMap &attribs)
178{
179 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
180}
181
Martin Radev9d901792016-07-15 15:58:58 +0300182std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
183{
184 std::string labelName;
185 if (label != nullptr)
186 {
187 size_t labelLength = length < 0 ? strlen(label) : length;
188 labelName = std::string(label, labelLength);
189 }
190 return labelName;
191}
192
193void GetObjectLabelBase(const std::string &objectLabel,
194 GLsizei bufSize,
195 GLsizei *length,
196 GLchar *label)
197{
198 size_t writeLength = objectLabel.length();
199 if (label != nullptr && bufSize > 0)
200 {
201 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
202 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
203 label[writeLength] = '\0';
204 }
205
206 if (length != nullptr)
207 {
208 *length = static_cast<GLsizei>(writeLength);
209 }
210}
211
Geoff Langf6db0982015-08-25 13:04:00 -0400212} // anonymous namespace
213
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000214namespace gl
215{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000216
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400217Context::Context(rx::EGLImplFactory *implFactory,
218 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400219 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500220 const egl::AttributeMap &attribs)
Martin Radev1be913c2016-07-11 17:59:16 +0300221
222 : ValidationContext(GetClientMajorVersion(attribs),
223 GetClientMinorVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700224 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500225 mCaps,
226 mTextureCaps,
227 mExtensions,
228 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500229 mLimitations,
230 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700231 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500232 mCompiler(nullptr),
Martin Radev1be913c2016-07-11 17:59:16 +0300233 mClientMajorVersion(GetClientMajorVersion(attribs)),
234 mClientMinorVersion(GetClientMinorVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400235 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500236 mClientType(EGL_OPENGL_ES_API),
237 mHasBeenCurrent(false),
238 mContextLost(false),
239 mResetStatus(GL_NO_ERROR),
240 mResetStrategy(GetResetStrategy(attribs)),
241 mRobustAccess(GetRobustAccess(attribs)),
242 mCurrentSurface(nullptr),
243 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000244{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500245 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000246
Jamie Madill00ed7a12016-05-19 13:13:38 -0400247 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400248
Martin Radev1be913c2016-07-11 17:59:16 +0300249 mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100250
Shannon Woods53a94a82014-06-24 15:20:36 -0400251 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400252
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400253 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000254 {
255 mResourceManager = shareContext->mResourceManager;
256 mResourceManager->addRef();
257 }
258 else
259 {
Jamie Madill901b3792016-05-26 09:20:40 -0400260 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000261 }
262
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700263 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400264
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000265 // [OpenGL ES 2.0.24] section 3.7 page 83:
266 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
267 // and cube map texture state vectors respectively associated with them.
268 // In order that access to these initial textures not be lost, they are treated as texture
269 // objects all of whose names are 0.
270
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400271 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500272 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500273
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400274 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500275 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400276
Martin Radev1be913c2016-07-11 17:59:16 +0300277 if (mClientMajorVersion >= 3)
Geoff Lang76b10c92014-09-05 16:28:14 -0400278 {
279 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400280 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500281 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400282
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400283 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500284 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400285 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286
Ian Ewellbda75592016-04-18 17:25:54 -0400287 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
288 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400289 Texture *zeroTextureExternal =
290 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400291 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
292 }
293
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700294 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500295
Jamie Madill57a89722013-07-02 11:57:03 -0400296 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000297 bindArrayBuffer(0);
298 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400299
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000300 bindRenderbuffer(0);
301
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000302 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400303 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000304 {
305 bindIndexedUniformBuffer(0, i, 0, -1);
306 }
307
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000308 bindCopyReadBuffer(0);
309 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000310 bindPixelPackBuffer(0);
311 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000312
Martin Radev1be913c2016-07-11 17:59:16 +0300313 if (mClientMajorVersion >= 3)
Geoff Lang1a683462015-09-29 15:09:59 -0400314 {
315 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
316 // In the initial state, a default transform feedback object is bound and treated as
317 // a transform feedback object with a name of zero. That object is bound any time
318 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400319 bindTransformFeedback(0);
320 }
Geoff Langc8058452014-02-03 12:04:11 -0500321
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700322 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500323
324 // Initialize dirty bit masks
325 // TODO(jmadill): additional ES3 state
326 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
327 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
328 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
329 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
330 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
331 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400332 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500333 // No dirty objects.
334
335 // Readpixels uses the pack state and read FBO
336 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
337 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
338 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
339 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
340 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400341 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500342 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
343
344 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
345 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
346 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
347 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
348 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
349 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
350 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
351 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
352 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
353 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
354 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
355 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
356
357 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
358 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
359 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
360 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400361
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400362 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000363}
364
365Context::~Context()
366{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700367 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000368
Corentin Wallez37c39792015-08-20 14:19:46 -0400369 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400371 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400372 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400373 {
374 SafeDelete(framebuffer.second);
375 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000376 }
377
Corentin Wallez80b24112015-08-25 16:41:57 -0400378 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000379 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400380 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000381 }
382
Corentin Wallez80b24112015-08-25 16:41:57 -0400383 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000384 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400385 if (query.second != nullptr)
386 {
387 query.second->release();
388 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389 }
390
Corentin Wallez80b24112015-08-25 16:41:57 -0400391 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400392 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400393 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400394 }
395
Corentin Wallez80b24112015-08-25 16:41:57 -0400396 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500397 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500398 if (transformFeedback.second != nullptr)
399 {
400 transformFeedback.second->release();
401 }
Geoff Langc8058452014-02-03 12:04:11 -0500402 }
403
Jamie Madilldedd7b92014-11-05 16:30:36 -0500404 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400405 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500406 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400407 }
408 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000409
Corentin Wallez51706ea2015-08-07 14:39:22 -0400410 if (mCurrentSurface != nullptr)
411 {
412 releaseSurface();
413 }
414
Jamie Madill1e9ae072014-11-06 15:27:21 -0500415 if (mResourceManager)
416 {
417 mResourceManager->release();
418 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500419
420 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421}
422
daniel@transgaming.comad629872012-11-28 19:32:06 +0000423void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000424{
Jamie Madill77a72f62015-04-14 11:18:32 -0400425 ASSERT(surface != nullptr);
426
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427 if (!mHasBeenCurrent)
428 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400430 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700432 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
433 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000434
435 mHasBeenCurrent = true;
436 }
437
Jamie Madill1b94d432015-08-07 13:23:23 -0400438 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700439 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400440
Corentin Wallez51706ea2015-08-07 14:39:22 -0400441 if (mCurrentSurface)
442 {
443 releaseSurface();
444 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000445 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400446 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000447
Corentin Wallez37c39792015-08-20 14:19:46 -0400448 // Update default framebuffer, the binding of the previous default
449 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400450 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400451 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700452 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400453 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700454 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400455 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700456 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400457 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700458 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400459 }
460 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400461 }
Ian Ewell292f0052016-02-04 10:37:32 -0500462
463 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700464 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465}
466
Jamie Madill77a72f62015-04-14 11:18:32 -0400467void Context::releaseSurface()
468{
Corentin Wallez37c39792015-08-20 14:19:46 -0400469 ASSERT(mCurrentSurface != nullptr);
470
471 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400472 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400473 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700474 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400475 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700476 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400477 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700478 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400479 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700480 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400481 }
482 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400483 }
484
Corentin Wallez51706ea2015-08-07 14:39:22 -0400485 mCurrentSurface->setIsCurrent(false);
486 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400487}
488
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000489GLuint Context::createBuffer()
490{
491 return mResourceManager->createBuffer();
492}
493
494GLuint Context::createProgram()
495{
Jamie Madill901b3792016-05-26 09:20:40 -0400496 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000497}
498
499GLuint Context::createShader(GLenum type)
500{
Jamie Madill901b3792016-05-26 09:20:40 -0400501 return mResourceManager->createShader(mImplementation.get(),
502 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000503}
504
505GLuint Context::createTexture()
506{
507 return mResourceManager->createTexture();
508}
509
510GLuint Context::createRenderbuffer()
511{
512 return mResourceManager->createRenderbuffer();
513}
514
Geoff Lang882033e2014-09-30 11:26:07 -0400515GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400516{
Jamie Madill901b3792016-05-26 09:20:40 -0400517 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400518
Cooper Partind8e62a32015-01-29 15:21:25 -0800519 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400520}
521
Sami Väisänene45e53b2016-05-25 10:36:04 +0300522GLuint Context::createPaths(GLsizei range)
523{
524 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
525 if (resultOrError.isError())
526 {
527 handleError(resultOrError.getError());
528 return 0;
529 }
530 return resultOrError.getResult();
531}
532
Jamie Madill57a89722013-07-02 11:57:03 -0400533GLuint Context::createVertexArray()
534{
Geoff Lang36167ab2015-12-07 10:27:14 -0500535 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
536 mVertexArrayMap[vertexArray] = nullptr;
537 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400538}
539
Jamie Madilldc356042013-07-19 16:36:57 -0400540GLuint Context::createSampler()
541{
542 return mResourceManager->createSampler();
543}
544
Geoff Langc8058452014-02-03 12:04:11 -0500545GLuint Context::createTransformFeedback()
546{
Geoff Lang36167ab2015-12-07 10:27:14 -0500547 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
548 mTransformFeedbackMap[transformFeedback] = nullptr;
549 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500550}
551
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552// Returns an unused framebuffer name
553GLuint Context::createFramebuffer()
554{
555 GLuint handle = mFramebufferHandleAllocator.allocate();
556
557 mFramebufferMap[handle] = NULL;
558
559 return handle;
560}
561
Jamie Madill33dc8432013-07-26 11:55:05 -0400562GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563{
Jamie Madill33dc8432013-07-26 11:55:05 -0400564 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000565
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400566 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000567
568 return handle;
569}
570
571// Returns an unused query name
572GLuint Context::createQuery()
573{
574 GLuint handle = mQueryHandleAllocator.allocate();
575
576 mQueryMap[handle] = NULL;
577
578 return handle;
579}
580
581void Context::deleteBuffer(GLuint buffer)
582{
583 if (mResourceManager->getBuffer(buffer))
584 {
585 detachBuffer(buffer);
586 }
Jamie Madill893ab082014-05-16 16:56:10 -0400587
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588 mResourceManager->deleteBuffer(buffer);
589}
590
591void Context::deleteShader(GLuint shader)
592{
593 mResourceManager->deleteShader(shader);
594}
595
596void Context::deleteProgram(GLuint program)
597{
598 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599}
600
601void Context::deleteTexture(GLuint texture)
602{
603 if (mResourceManager->getTexture(texture))
604 {
605 detachTexture(texture);
606 }
607
608 mResourceManager->deleteTexture(texture);
609}
610
611void Context::deleteRenderbuffer(GLuint renderbuffer)
612{
613 if (mResourceManager->getRenderbuffer(renderbuffer))
614 {
615 detachRenderbuffer(renderbuffer);
616 }
Jamie Madill893ab082014-05-16 16:56:10 -0400617
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000618 mResourceManager->deleteRenderbuffer(renderbuffer);
619}
620
Jamie Madillcd055f82013-07-26 11:55:15 -0400621void Context::deleteFenceSync(GLsync fenceSync)
622{
623 // The spec specifies the underlying Fence object is not deleted until all current
624 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
625 // and since our API is currently designed for being called from a single thread, we can delete
626 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700627 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400628}
629
Sami Väisänene45e53b2016-05-25 10:36:04 +0300630void Context::deletePaths(GLuint first, GLsizei range)
631{
632 mResourceManager->deletePaths(first, range);
633}
634
635bool Context::hasPathData(GLuint path) const
636{
637 const auto *pathObj = mResourceManager->getPath(path);
638 if (pathObj == nullptr)
639 return false;
640
641 return pathObj->hasPathData();
642}
643
644bool Context::hasPath(GLuint path) const
645{
646 return mResourceManager->hasPath(path);
647}
648
649void Context::setPathCommands(GLuint path,
650 GLsizei numCommands,
651 const GLubyte *commands,
652 GLsizei numCoords,
653 GLenum coordType,
654 const void *coords)
655{
656 auto *pathObject = mResourceManager->getPath(path);
657
658 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
659}
660
661void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
662{
663 auto *pathObj = mResourceManager->getPath(path);
664
665 switch (pname)
666 {
667 case GL_PATH_STROKE_WIDTH_CHROMIUM:
668 pathObj->setStrokeWidth(value);
669 break;
670 case GL_PATH_END_CAPS_CHROMIUM:
671 pathObj->setEndCaps(static_cast<GLenum>(value));
672 break;
673 case GL_PATH_JOIN_STYLE_CHROMIUM:
674 pathObj->setJoinStyle(static_cast<GLenum>(value));
675 break;
676 case GL_PATH_MITER_LIMIT_CHROMIUM:
677 pathObj->setMiterLimit(value);
678 break;
679 case GL_PATH_STROKE_BOUND_CHROMIUM:
680 pathObj->setStrokeBound(value);
681 break;
682 default:
683 UNREACHABLE();
684 break;
685 }
686}
687
688void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
689{
690 const auto *pathObj = mResourceManager->getPath(path);
691
692 switch (pname)
693 {
694 case GL_PATH_STROKE_WIDTH_CHROMIUM:
695 *value = pathObj->getStrokeWidth();
696 break;
697 case GL_PATH_END_CAPS_CHROMIUM:
698 *value = static_cast<GLfloat>(pathObj->getEndCaps());
699 break;
700 case GL_PATH_JOIN_STYLE_CHROMIUM:
701 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
702 break;
703 case GL_PATH_MITER_LIMIT_CHROMIUM:
704 *value = pathObj->getMiterLimit();
705 break;
706 case GL_PATH_STROKE_BOUND_CHROMIUM:
707 *value = pathObj->getStrokeBound();
708 break;
709 default:
710 UNREACHABLE();
711 break;
712 }
713}
714
715void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
716{
717 mGLState.setPathStencilFunc(func, ref, mask);
718}
719
Jamie Madill57a89722013-07-02 11:57:03 -0400720void Context::deleteVertexArray(GLuint vertexArray)
721{
Geoff Lang36167ab2015-12-07 10:27:14 -0500722 auto iter = mVertexArrayMap.find(vertexArray);
723 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000724 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500725 VertexArray *vertexArrayObject = iter->second;
726 if (vertexArrayObject != nullptr)
727 {
728 detachVertexArray(vertexArray);
729 delete vertexArrayObject;
730 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000731
Geoff Lang36167ab2015-12-07 10:27:14 -0500732 mVertexArrayMap.erase(iter);
733 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400734 }
735}
736
Jamie Madilldc356042013-07-19 16:36:57 -0400737void Context::deleteSampler(GLuint sampler)
738{
739 if (mResourceManager->getSampler(sampler))
740 {
741 detachSampler(sampler);
742 }
743
744 mResourceManager->deleteSampler(sampler);
745}
746
Geoff Langc8058452014-02-03 12:04:11 -0500747void Context::deleteTransformFeedback(GLuint transformFeedback)
748{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500749 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500750 if (iter != mTransformFeedbackMap.end())
751 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500752 TransformFeedback *transformFeedbackObject = iter->second;
753 if (transformFeedbackObject != nullptr)
754 {
755 detachTransformFeedback(transformFeedback);
756 transformFeedbackObject->release();
757 }
758
Geoff Lang50b3fe82015-12-08 14:49:12 +0000759 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500760 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500761 }
762}
763
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000764void Context::deleteFramebuffer(GLuint framebuffer)
765{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500766 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000767
768 if (framebufferObject != mFramebufferMap.end())
769 {
770 detachFramebuffer(framebuffer);
771
772 mFramebufferHandleAllocator.release(framebufferObject->first);
773 delete framebufferObject->second;
774 mFramebufferMap.erase(framebufferObject);
775 }
776}
777
Jamie Madill33dc8432013-07-26 11:55:05 -0400778void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500780 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000781
Jamie Madill33dc8432013-07-26 11:55:05 -0400782 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400784 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000785 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400786 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787 }
788}
789
790void Context::deleteQuery(GLuint query)
791{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500792 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793 if (queryObject != mQueryMap.end())
794 {
795 mQueryHandleAllocator.release(queryObject->first);
796 if (queryObject->second)
797 {
798 queryObject->second->release();
799 }
800 mQueryMap.erase(queryObject);
801 }
802}
803
Geoff Lang70d0f492015-12-10 17:45:46 -0500804Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805{
806 return mResourceManager->getBuffer(handle);
807}
808
Geoff Lang48dcae72014-02-05 16:28:24 -0500809Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810{
811 return mResourceManager->getShader(handle);
812}
813
Geoff Lang48dcae72014-02-05 16:28:24 -0500814Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815{
816 return mResourceManager->getProgram(handle);
817}
818
Jamie Madill570f7c82014-07-03 10:38:54 -0400819Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820{
821 return mResourceManager->getTexture(handle);
822}
823
Geoff Lang70d0f492015-12-10 17:45:46 -0500824Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825{
826 return mResourceManager->getRenderbuffer(handle);
827}
828
Jamie Madillcd055f82013-07-26 11:55:15 -0400829FenceSync *Context::getFenceSync(GLsync handle) const
830{
Minmin Gong794e0002015-04-07 18:31:54 -0700831 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400832}
833
Jamie Madill57a89722013-07-02 11:57:03 -0400834VertexArray *Context::getVertexArray(GLuint handle) const
835{
836 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500837 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400838}
839
Jamie Madilldc356042013-07-19 16:36:57 -0400840Sampler *Context::getSampler(GLuint handle) const
841{
842 return mResourceManager->getSampler(handle);
843}
844
Geoff Langc8058452014-02-03 12:04:11 -0500845TransformFeedback *Context::getTransformFeedback(GLuint handle) const
846{
Geoff Lang36167ab2015-12-07 10:27:14 -0500847 auto iter = mTransformFeedbackMap.find(handle);
848 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500849}
850
Geoff Lang70d0f492015-12-10 17:45:46 -0500851LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
852{
853 switch (identifier)
854 {
855 case GL_BUFFER:
856 return getBuffer(name);
857 case GL_SHADER:
858 return getShader(name);
859 case GL_PROGRAM:
860 return getProgram(name);
861 case GL_VERTEX_ARRAY:
862 return getVertexArray(name);
863 case GL_QUERY:
864 return getQuery(name);
865 case GL_TRANSFORM_FEEDBACK:
866 return getTransformFeedback(name);
867 case GL_SAMPLER:
868 return getSampler(name);
869 case GL_TEXTURE:
870 return getTexture(name);
871 case GL_RENDERBUFFER:
872 return getRenderbuffer(name);
873 case GL_FRAMEBUFFER:
874 return getFramebuffer(name);
875 default:
876 UNREACHABLE();
877 return nullptr;
878 }
879}
880
881LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
882{
883 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
884}
885
Martin Radev9d901792016-07-15 15:58:58 +0300886void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
887{
888 LabeledObject *object = getLabeledObject(identifier, name);
889 ASSERT(object != nullptr);
890
891 std::string labelName = GetObjectLabelFromPointer(length, label);
892 object->setLabel(labelName);
893}
894
895void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
896{
897 LabeledObject *object = getLabeledObjectFromPtr(ptr);
898 ASSERT(object != nullptr);
899
900 std::string labelName = GetObjectLabelFromPointer(length, label);
901 object->setLabel(labelName);
902}
903
904void Context::getObjectLabel(GLenum identifier,
905 GLuint name,
906 GLsizei bufSize,
907 GLsizei *length,
908 GLchar *label) const
909{
910 LabeledObject *object = getLabeledObject(identifier, name);
911 ASSERT(object != nullptr);
912
913 const std::string &objectLabel = object->getLabel();
914 GetObjectLabelBase(objectLabel, bufSize, length, label);
915}
916
917void Context::getObjectPtrLabel(const void *ptr,
918 GLsizei bufSize,
919 GLsizei *length,
920 GLchar *label) const
921{
922 LabeledObject *object = getLabeledObjectFromPtr(ptr);
923 ASSERT(object != nullptr);
924
925 const std::string &objectLabel = object->getLabel();
926 GetObjectLabelBase(objectLabel, bufSize, length, label);
927}
928
Jamie Madilldc356042013-07-19 16:36:57 -0400929bool Context::isSampler(GLuint samplerName) const
930{
931 return mResourceManager->isSampler(samplerName);
932}
933
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500934void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000935{
Jamie Madill901b3792016-05-26 09:20:40 -0400936 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700937 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000938}
939
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500940void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000941{
Jamie Madill901b3792016-05-26 09:20:40 -0400942 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700943 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000944}
945
Jamie Madilldedd7b92014-11-05 16:30:36 -0500946void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500948 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000949
Jamie Madilldedd7b92014-11-05 16:30:36 -0500950 if (handle == 0)
951 {
952 texture = mZeroTextures[target].get();
953 }
954 else
955 {
Jamie Madill901b3792016-05-26 09:20:40 -0400956 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500957 }
958
959 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700960 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000961}
962
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500963void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000964{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500965 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700966 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000967}
968
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500969void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500971 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973}
974
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500975void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976{
Jamie Madill901b3792016-05-26 09:20:40 -0400977 Renderbuffer *renderbuffer =
978 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700979 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980}
981
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500982void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400983{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500984 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700985 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400986}
987
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400989{
Geoff Lang76b10c92014-09-05 16:28:14 -0400990 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400991 Sampler *sampler =
992 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700993 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400994}
995
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500996void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000997{
Jamie Madill901b3792016-05-26 09:20:40 -0400998 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700999 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001000}
1001
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001002void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1003 GLuint index,
1004 GLintptr offset,
1005 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001006{
Jamie Madill901b3792016-05-26 09:20:40 -04001007 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001008 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001009}
1010
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001011void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001012{
Jamie Madill901b3792016-05-26 09:20:40 -04001013 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001014 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001015}
1016
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001017void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1018 GLuint index,
1019 GLintptr offset,
1020 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001021{
Jamie Madill901b3792016-05-26 09:20:40 -04001022 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001023 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001024}
1025
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001026void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001027{
Jamie Madill901b3792016-05-26 09:20:40 -04001028 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001029 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001030}
1031
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001032void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001033{
Jamie Madill901b3792016-05-26 09:20:40 -04001034 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001035 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001036}
1037
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001038void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001039{
Jamie Madill901b3792016-05-26 09:20:40 -04001040 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001041 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001042}
1043
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001044void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001045{
Jamie Madill901b3792016-05-26 09:20:40 -04001046 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001047 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001048}
1049
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001050void Context::useProgram(GLuint program)
1051{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001052 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001053}
1054
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001055void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001056{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001057 TransformFeedback *transformFeedback =
1058 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001059 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001060}
1061
Geoff Lang5aad9672014-09-08 11:10:42 -04001062Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001063{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001064 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001065 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001066
Geoff Lang5aad9672014-09-08 11:10:42 -04001067 // begin query
1068 Error error = queryObject->begin();
1069 if (error.isError())
1070 {
1071 return error;
1072 }
1073
1074 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001075 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076
Geoff Lang5aad9672014-09-08 11:10:42 -04001077 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001078}
1079
Geoff Lang5aad9672014-09-08 11:10:42 -04001080Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001081{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001082 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001083 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084
Geoff Lang5aad9672014-09-08 11:10:42 -04001085 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086
Geoff Lang5aad9672014-09-08 11:10:42 -04001087 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001088 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001089
1090 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091}
1092
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001093Error Context::queryCounter(GLuint id, GLenum target)
1094{
1095 ASSERT(target == GL_TIMESTAMP_EXT);
1096
1097 Query *queryObject = getQuery(id, true, target);
1098 ASSERT(queryObject);
1099
1100 return queryObject->queryCounter();
1101}
1102
1103void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1104{
1105 switch (pname)
1106 {
1107 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001108 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001109 break;
1110 case GL_QUERY_COUNTER_BITS_EXT:
1111 switch (target)
1112 {
1113 case GL_TIME_ELAPSED_EXT:
1114 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1115 break;
1116 case GL_TIMESTAMP_EXT:
1117 params[0] = getExtensions().queryCounterBitsTimestamp;
1118 break;
1119 default:
1120 UNREACHABLE();
1121 params[0] = 0;
1122 break;
1123 }
1124 break;
1125 default:
1126 UNREACHABLE();
1127 return;
1128 }
1129}
1130
1131Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1132{
1133 return GetQueryObjectParameter(this, id, pname, params);
1134}
1135
1136Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1137{
1138 return GetQueryObjectParameter(this, id, pname, params);
1139}
1140
1141Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1142{
1143 return GetQueryObjectParameter(this, id, pname, params);
1144}
1145
1146Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1147{
1148 return GetQueryObjectParameter(this, id, pname, params);
1149}
1150
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001151Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001152{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001153 auto framebufferIt = mFramebufferMap.find(handle);
1154 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001155}
1156
Jamie Madill33dc8432013-07-26 11:55:05 -04001157FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001159 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001160
Jamie Madill33dc8432013-07-26 11:55:05 -04001161 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162 {
1163 return NULL;
1164 }
1165 else
1166 {
1167 return fence->second;
1168 }
1169}
1170
1171Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1172{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001173 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174
1175 if (query == mQueryMap.end())
1176 {
1177 return NULL;
1178 }
1179 else
1180 {
1181 if (!query->second && create)
1182 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001183 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184 query->second->addRef();
1185 }
1186 return query->second;
1187 }
1188}
1189
Geoff Lang70d0f492015-12-10 17:45:46 -05001190Query *Context::getQuery(GLuint handle) const
1191{
1192 auto iter = mQueryMap.find(handle);
1193 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1194}
1195
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001196Texture *Context::getTargetTexture(GLenum target) const
1197{
Ian Ewellbda75592016-04-18 17:25:54 -04001198 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001199 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001200}
1201
Geoff Lang76b10c92014-09-05 16:28:14 -04001202Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001204 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001205}
1206
Geoff Lang492a7e42014-11-05 13:27:06 -05001207Compiler *Context::getCompiler() const
1208{
1209 return mCompiler;
1210}
1211
Jamie Madill893ab082014-05-16 16:56:10 -04001212void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213{
1214 switch (pname)
1215 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001216 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001217 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001219 mGLState.getBooleanv(pname, params);
1220 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001221 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001222}
1223
Jamie Madill893ab082014-05-16 16:56:10 -04001224void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001225{
Shannon Woods53a94a82014-06-24 15:20:36 -04001226 // Queries about context capabilities and maximums are answered by Context.
1227 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001228 switch (pname)
1229 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001230 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001231 params[0] = mCaps.minAliasedLineWidth;
1232 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001233 break;
1234 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001235 params[0] = mCaps.minAliasedPointSize;
1236 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001238 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001239 ASSERT(mExtensions.textureFilterAnisotropic);
1240 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001241 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001242 case GL_MAX_TEXTURE_LOD_BIAS:
1243 *params = mCaps.maxLODBias;
1244 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001245
1246 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1247 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1248 {
1249 ASSERT(mExtensions.pathRendering);
1250 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1251 memcpy(params, m, 16 * sizeof(GLfloat));
1252 }
1253 break;
1254
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001256 mGLState.getFloatv(pname, params);
1257 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001259}
1260
Jamie Madill893ab082014-05-16 16:56:10 -04001261void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001262{
Shannon Woods53a94a82014-06-24 15:20:36 -04001263 // Queries about context capabilities and maximums are answered by Context.
1264 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001265
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266 switch (pname)
1267 {
Geoff Lang301d1612014-07-09 10:34:37 -04001268 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1269 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1270 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001271 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1272 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1273 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001274 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1275 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1276 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001277 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001278 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1279 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1280 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001281 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001282 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001283 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1284 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1285 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1286 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001287 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1288 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001289 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1290 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001291 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001292 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1293 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1294 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1295 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001296 case GL_MAJOR_VERSION:
1297 *params = mClientMajorVersion;
1298 break;
1299 case GL_MINOR_VERSION:
1300 *params = mClientMinorVersion;
1301 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001302 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1303 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001304 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1305 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1306 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001307 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1308 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1309 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001310 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001311 case GL_MAX_VIEWPORT_DIMS:
1312 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001313 params[0] = mCaps.maxViewportWidth;
1314 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001315 }
1316 break;
1317 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001318 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001319 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001320 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1321 *params = mResetStrategy;
1322 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001323 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001324 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001325 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001326 case GL_SHADER_BINARY_FORMATS:
1327 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1328 break;
1329 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001330 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001331 break;
1332 case GL_PROGRAM_BINARY_FORMATS:
1333 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001335 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001336 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001337 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001338
1339 // GL_KHR_debug
1340 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1341 *params = mExtensions.maxDebugMessageLength;
1342 break;
1343 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1344 *params = mExtensions.maxDebugLoggedMessages;
1345 break;
1346 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1347 *params = mExtensions.maxDebugGroupStackDepth;
1348 break;
1349 case GL_MAX_LABEL_LENGTH:
1350 *params = mExtensions.maxLabelLength;
1351 break;
1352
Ian Ewell53f59f42016-01-28 17:36:55 -05001353 // GL_EXT_disjoint_timer_query
1354 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001355 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001356 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001357 case GL_MAX_FRAMEBUFFER_WIDTH:
1358 *params = mCaps.maxFramebufferWidth;
1359 break;
1360 case GL_MAX_FRAMEBUFFER_HEIGHT:
1361 *params = mCaps.maxFramebufferHeight;
1362 break;
1363 case GL_MAX_FRAMEBUFFER_SAMPLES:
1364 *params = mCaps.maxFramebufferSamples;
1365 break;
1366 case GL_MAX_SAMPLE_MASK_WORDS:
1367 *params = mCaps.maxSampleMaskWords;
1368 break;
1369 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1370 *params = mCaps.maxColorTextureSamples;
1371 break;
1372 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1373 *params = mCaps.maxDepthTextureSamples;
1374 break;
1375 case GL_MAX_INTEGER_SAMPLES:
1376 *params = mCaps.maxIntegerSamples;
1377 break;
1378 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1379 *params = mCaps.maxVertexAttribRelativeOffset;
1380 break;
1381 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1382 *params = mCaps.maxVertexAttribBindings;
1383 break;
1384 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1385 *params = mCaps.maxVertexAttribStride;
1386 break;
1387 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1388 *params = mCaps.maxVertexAtomicCounterBuffers;
1389 break;
1390 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1391 *params = mCaps.maxVertexAtomicCounters;
1392 break;
1393 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1394 *params = mCaps.maxVertexImageUniforms;
1395 break;
1396 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1397 *params = mCaps.maxVertexShaderStorageBlocks;
1398 break;
1399 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1400 *params = mCaps.maxFragmentAtomicCounterBuffers;
1401 break;
1402 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1403 *params = mCaps.maxFragmentAtomicCounters;
1404 break;
1405 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1406 *params = mCaps.maxFragmentImageUniforms;
1407 break;
1408 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1409 *params = mCaps.maxFragmentShaderStorageBlocks;
1410 break;
1411 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1412 *params = mCaps.minProgramTextureGatherOffset;
1413 break;
1414 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1415 *params = mCaps.maxProgramTextureGatherOffset;
1416 break;
1417 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1418 *params = mCaps.maxComputeWorkGroupInvocations;
1419 break;
1420 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1421 *params = mCaps.maxComputeUniformBlocks;
1422 break;
1423 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1424 *params = mCaps.maxComputeTextureImageUnits;
1425 break;
1426 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1427 *params = mCaps.maxComputeSharedMemorySize;
1428 break;
1429 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1430 *params = mCaps.maxComputeUniformComponents;
1431 break;
1432 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1433 *params = mCaps.maxComputeAtomicCounterBuffers;
1434 break;
1435 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1436 *params = mCaps.maxComputeAtomicCounters;
1437 break;
1438 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1439 *params = mCaps.maxComputeImageUniforms;
1440 break;
1441 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1442 *params = mCaps.maxCombinedComputeUniformComponents;
1443 break;
1444 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1445 *params = mCaps.maxComputeShaderStorageBlocks;
1446 break;
1447 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1448 *params = mCaps.maxCombinedShaderOutputResources;
1449 break;
1450 case GL_MAX_UNIFORM_LOCATIONS:
1451 *params = mCaps.maxUniformLocations;
1452 break;
1453 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1454 *params = mCaps.maxAtomicCounterBufferBindings;
1455 break;
1456 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1457 *params = mCaps.maxAtomicCounterBufferSize;
1458 break;
1459 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1460 *params = mCaps.maxCombinedAtomicCounterBuffers;
1461 break;
1462 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1463 *params = mCaps.maxCombinedAtomicCounters;
1464 break;
1465 case GL_MAX_IMAGE_UNITS:
1466 *params = mCaps.maxImageUnits;
1467 break;
1468 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1469 *params = mCaps.maxCombinedImageUniforms;
1470 break;
1471 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1472 *params = mCaps.maxShaderStorageBufferBindings;
1473 break;
1474 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1475 *params = mCaps.maxCombinedShaderStorageBlocks;
1476 break;
1477 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1478 *params = mCaps.shaderStorageBufferOffsetAlignment;
1479 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001480 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001481 mGLState.getIntegerv(mState, pname, params);
1482 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001484}
1485
Jamie Madill893ab082014-05-16 16:56:10 -04001486void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001487{
Shannon Woods53a94a82014-06-24 15:20:36 -04001488 // Queries about context capabilities and maximums are answered by Context.
1489 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001490 switch (pname)
1491 {
1492 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001493 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001494 break;
1495 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001496 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001497 break;
1498 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001499 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001500 break;
1501 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001502 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001503 break;
1504 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001505 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001506 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001507
1508 // GL_EXT_disjoint_timer_query
1509 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001510 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001511 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001512
1513 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1514 *params = mCaps.maxShaderStorageBlockSize;
1515 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001516 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001517 UNREACHABLE();
1518 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001519 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001520}
1521
Geoff Lang70d0f492015-12-10 17:45:46 -05001522void Context::getPointerv(GLenum pname, void **params) const
1523{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001524 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001525}
1526
Martin Radev66fb8202016-07-28 11:45:20 +03001527void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001528{
Shannon Woods53a94a82014-06-24 15:20:36 -04001529 // Queries about context capabilities and maximums are answered by Context.
1530 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001531
1532 GLenum nativeType;
1533 unsigned int numParams;
1534 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001535 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001536 ASSERT(queryStatus);
1537
1538 if (nativeType == GL_INT)
1539 {
1540 switch (target)
1541 {
1542 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1543 ASSERT(index < 3u);
1544 *data = mCaps.maxComputeWorkGroupCount[index];
1545 break;
1546 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1547 ASSERT(index < 3u);
1548 *data = mCaps.maxComputeWorkGroupSize[index];
1549 break;
1550 default:
1551 mGLState.getIntegeri_v(target, index, data);
1552 }
1553 }
1554 else
1555 {
1556 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1557 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001558}
1559
Martin Radev66fb8202016-07-28 11:45:20 +03001560void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001561{
Shannon Woods53a94a82014-06-24 15:20:36 -04001562 // Queries about context capabilities and maximums are answered by Context.
1563 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001564
1565 GLenum nativeType;
1566 unsigned int numParams;
1567 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001568 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001569 ASSERT(queryStatus);
1570
1571 if (nativeType == GL_INT_64_ANGLEX)
1572 {
1573 mGLState.getInteger64i_v(target, index, data);
1574 }
1575 else
1576 {
1577 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1578 }
1579}
1580
1581void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1582{
1583 // Queries about context capabilities and maximums are answered by Context.
1584 // Queries about current GL state values are answered by State.
1585
1586 GLenum nativeType;
1587 unsigned int numParams;
1588 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
Geoff Lange1c4d392016-08-04 11:44:34 -04001589 UNUSED_ASSERTION_VARIABLE(queryStatus);
Martin Radev66fb8202016-07-28 11:45:20 +03001590 ASSERT(queryStatus);
1591
1592 if (nativeType == GL_BOOL)
1593 {
1594 mGLState.getBooleani_v(target, index, data);
1595 }
1596 else
1597 {
1598 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1599 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001600}
1601
Geoff Langf6db0982015-08-25 13:04:00 -04001602Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001603{
Jamie Madill1b94d432015-08-07 13:23:23 -04001604 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001605 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001606 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001607
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001608 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001609}
1610
Geoff Langf6db0982015-08-25 13:04:00 -04001611Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1612{
1613 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001614 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001615 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001616
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001617 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001618}
1619
1620Error Context::drawElements(GLenum mode,
1621 GLsizei count,
1622 GLenum type,
1623 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001624 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001625{
Jamie Madill1b94d432015-08-07 13:23:23 -04001626 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001627 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001628}
1629
1630Error Context::drawElementsInstanced(GLenum mode,
1631 GLsizei count,
1632 GLenum type,
1633 const GLvoid *indices,
1634 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001635 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001636{
1637 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001638 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1639 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001640}
1641
1642Error Context::drawRangeElements(GLenum mode,
1643 GLuint start,
1644 GLuint end,
1645 GLsizei count,
1646 GLenum type,
1647 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001648 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001649{
1650 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001651 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001652}
1653
Geoff Lang129753a2015-01-09 16:52:09 -05001654Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001655{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001656 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001657}
1658
1659Error Context::finish()
1660{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001661 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001662}
1663
Austin Kinross6ee1e782015-05-29 17:05:37 -07001664void Context::insertEventMarker(GLsizei length, const char *marker)
1665{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001666 ASSERT(mImplementation);
1667 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001668}
1669
1670void Context::pushGroupMarker(GLsizei length, const char *marker)
1671{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001672 ASSERT(mImplementation);
1673 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001674}
1675
1676void Context::popGroupMarker()
1677{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001678 ASSERT(mImplementation);
1679 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001680}
1681
Geoff Langd8605522016-04-13 10:19:12 -04001682void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1683{
1684 Program *programObject = getProgram(program);
1685 ASSERT(programObject);
1686
1687 programObject->bindUniformLocation(location, name);
1688}
1689
Sami Väisänena797e062016-05-12 15:23:40 +03001690void Context::setCoverageModulation(GLenum components)
1691{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001692 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001693}
1694
Sami Väisänene45e53b2016-05-25 10:36:04 +03001695void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1696{
1697 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1698}
1699
1700void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1701{
1702 GLfloat I[16];
1703 angle::Matrix<GLfloat>::setToIdentity(I);
1704
1705 mGLState.loadPathRenderingMatrix(matrixMode, I);
1706}
1707
1708void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1709{
1710 const auto *pathObj = mResourceManager->getPath(path);
1711 if (!pathObj)
1712 return;
1713
1714 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1715 syncRendererState();
1716
1717 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1718}
1719
1720void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1721{
1722 const auto *pathObj = mResourceManager->getPath(path);
1723 if (!pathObj)
1724 return;
1725
1726 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1727 syncRendererState();
1728
1729 mImplementation->stencilStrokePath(pathObj, reference, mask);
1730}
1731
1732void Context::coverFillPath(GLuint path, GLenum coverMode)
1733{
1734 const auto *pathObj = mResourceManager->getPath(path);
1735 if (!pathObj)
1736 return;
1737
1738 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1739 syncRendererState();
1740
1741 mImplementation->coverFillPath(pathObj, coverMode);
1742}
1743
1744void Context::coverStrokePath(GLuint path, GLenum coverMode)
1745{
1746 const auto *pathObj = mResourceManager->getPath(path);
1747 if (!pathObj)
1748 return;
1749
1750 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1751 syncRendererState();
1752
1753 mImplementation->coverStrokePath(pathObj, coverMode);
1754}
1755
1756void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1757{
1758 const auto *pathObj = mResourceManager->getPath(path);
1759 if (!pathObj)
1760 return;
1761
1762 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1763 syncRendererState();
1764
1765 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1766}
1767
1768void Context::stencilThenCoverStrokePath(GLuint path,
1769 GLint reference,
1770 GLuint mask,
1771 GLenum coverMode)
1772{
1773 const auto *pathObj = mResourceManager->getPath(path);
1774 if (!pathObj)
1775 return;
1776
1777 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1778 syncRendererState();
1779
1780 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1781}
1782
Sami Väisänend59ca052016-06-21 16:10:00 +03001783void Context::coverFillPathInstanced(GLsizei numPaths,
1784 GLenum pathNameType,
1785 const void *paths,
1786 GLuint pathBase,
1787 GLenum coverMode,
1788 GLenum transformType,
1789 const GLfloat *transformValues)
1790{
1791 const auto &pathObjects =
1792 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1793
1794 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1795 syncRendererState();
1796
1797 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1798}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001799
Sami Väisänend59ca052016-06-21 16:10:00 +03001800void Context::coverStrokePathInstanced(GLsizei numPaths,
1801 GLenum pathNameType,
1802 const void *paths,
1803 GLuint pathBase,
1804 GLenum coverMode,
1805 GLenum transformType,
1806 const GLfloat *transformValues)
1807{
1808 const auto &pathObjects =
1809 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1810
1811 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1812 syncRendererState();
1813
1814 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1815 transformValues);
1816}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001817
Sami Väisänend59ca052016-06-21 16:10:00 +03001818void Context::stencilFillPathInstanced(GLsizei numPaths,
1819 GLenum pathNameType,
1820 const void *paths,
1821 GLuint pathBase,
1822 GLenum fillMode,
1823 GLuint mask,
1824 GLenum transformType,
1825 const GLfloat *transformValues)
1826{
1827 const auto &pathObjects =
1828 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1829
1830 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1831 syncRendererState();
1832
1833 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1834 transformValues);
1835}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001836
Sami Väisänend59ca052016-06-21 16:10:00 +03001837void Context::stencilStrokePathInstanced(GLsizei numPaths,
1838 GLenum pathNameType,
1839 const void *paths,
1840 GLuint pathBase,
1841 GLint reference,
1842 GLuint mask,
1843 GLenum transformType,
1844 const GLfloat *transformValues)
1845{
1846 const auto &pathObjects =
1847 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1848
1849 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1850 syncRendererState();
1851
1852 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1853 transformValues);
1854}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001855
Sami Väisänend59ca052016-06-21 16:10:00 +03001856void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1857 GLenum pathNameType,
1858 const void *paths,
1859 GLuint pathBase,
1860 GLenum fillMode,
1861 GLuint mask,
1862 GLenum coverMode,
1863 GLenum transformType,
1864 const GLfloat *transformValues)
1865{
1866 const auto &pathObjects =
1867 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1868
1869 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1870 syncRendererState();
1871
1872 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1873 transformType, transformValues);
1874}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001875
Sami Väisänend59ca052016-06-21 16:10:00 +03001876void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1877 GLenum pathNameType,
1878 const void *paths,
1879 GLuint pathBase,
1880 GLint reference,
1881 GLuint mask,
1882 GLenum coverMode,
1883 GLenum transformType,
1884 const GLfloat *transformValues)
1885{
1886 const auto &pathObjects =
1887 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1888
1889 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1890 syncRendererState();
1891
1892 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1893 transformType, transformValues);
1894}
1895
Sami Väisänen46eaa942016-06-29 10:26:37 +03001896void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1897{
1898 auto *programObject = getProgram(program);
1899
1900 programObject->bindFragmentInputLocation(location, name);
1901}
1902
1903void Context::programPathFragmentInputGen(GLuint program,
1904 GLint location,
1905 GLenum genMode,
1906 GLint components,
1907 const GLfloat *coeffs)
1908{
1909 auto *programObject = getProgram(program);
1910
1911 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1912}
1913
Jamie Madill437fa652016-05-03 15:13:24 -04001914void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001915{
Geoff Langda5777c2014-07-11 09:52:58 -04001916 if (error.isError())
1917 {
1918 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001919
1920 if (!error.getMessage().empty())
1921 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001922 auto *debug = &mGLState.getDebug();
1923 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1924 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001925 }
Geoff Langda5777c2014-07-11 09:52:58 -04001926 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001927}
1928
1929// Get one of the recorded errors and clear its flag, if any.
1930// [OpenGL ES 2.0.24] section 2.5 page 13.
1931GLenum Context::getError()
1932{
Geoff Langda5777c2014-07-11 09:52:58 -04001933 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001934 {
Geoff Langda5777c2014-07-11 09:52:58 -04001935 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936 }
Geoff Langda5777c2014-07-11 09:52:58 -04001937 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001938 {
Geoff Langda5777c2014-07-11 09:52:58 -04001939 GLenum error = *mErrors.begin();
1940 mErrors.erase(mErrors.begin());
1941 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001942 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001943}
1944
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001945// NOTE: this function should not assume that this context is current!
1946void Context::markContextLost()
1947{
1948 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
1949 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
1950 mContextLost = true;
1951}
1952
1953bool Context::isContextLost()
1954{
1955 return mContextLost;
1956}
1957
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001958GLenum Context::getResetStatus()
1959{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001960 // Even if the application doesn't want to know about resets, we want to know
1961 // as it will allow us to skip all the calls.
1962 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001963 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001964 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001965 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001966 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001967 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001968
1969 // EXT_robustness, section 2.6: If the reset notification behavior is
1970 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
1971 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
1972 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001973 }
1974
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001975 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
1976 // status should be returned at least once, and GL_NO_ERROR should be returned
1977 // once the device has finished resetting.
1978 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001979 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001980 ASSERT(mResetStatus == GL_NO_ERROR);
1981 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001982
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001983 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001985 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001986 }
1987 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001988 else if (mResetStatus != GL_NO_ERROR)
1989 {
1990 mResetStatus = mImplementation->getResetStatus();
1991 }
Jamie Madill893ab082014-05-16 16:56:10 -04001992
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001993 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001994}
1995
1996bool Context::isResetNotificationEnabled()
1997{
1998 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1999}
2000
Corentin Walleze3b10e82015-05-20 11:06:25 -04002001const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002002{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002003 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002004}
2005
2006EGLenum Context::getClientType() const
2007{
2008 return mClientType;
2009}
2010
2011EGLenum Context::getRenderBuffer() const
2012{
Corentin Wallez37c39792015-08-20 14:19:46 -04002013 auto framebufferIt = mFramebufferMap.find(0);
2014 if (framebufferIt != mFramebufferMap.end())
2015 {
2016 const Framebuffer *framebuffer = framebufferIt->second;
2017 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2018
2019 ASSERT(backAttachment != nullptr);
2020 return backAttachment->getSurface()->getRenderBuffer();
2021 }
2022 else
2023 {
2024 return EGL_NONE;
2025 }
Régis Fénéon83107972015-02-05 12:57:44 +01002026}
2027
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002028VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002029{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002030 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002031 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2032 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002033 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002034 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002036 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002037 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002038
2039 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002040}
2041
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002042TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002043{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002044 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002045 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2046 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002047 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002048 transformFeedback =
2049 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002050 transformFeedback->addRef();
2051 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002052 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002053
2054 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002055}
2056
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002057Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
2058{
2059 // Can be called from Bind without a prior call to Gen.
2060 auto framebufferIt = mFramebufferMap.find(framebuffer);
2061 bool neverCreated = framebufferIt == mFramebufferMap.end();
2062 if (neverCreated || framebufferIt->second == nullptr)
2063 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002064 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002065 if (neverCreated)
2066 {
2067 mFramebufferHandleAllocator.reserve(framebuffer);
2068 mFramebufferMap[framebuffer] = newFBO;
2069 return newFBO;
2070 }
2071
2072 framebufferIt->second = newFBO;
2073 }
2074
2075 return framebufferIt->second;
2076}
2077
Geoff Lang36167ab2015-12-07 10:27:14 -05002078bool Context::isVertexArrayGenerated(GLuint vertexArray)
2079{
2080 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2081}
2082
2083bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2084{
2085 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2086}
2087
Shannon Woods53a94a82014-06-24 15:20:36 -04002088void Context::detachTexture(GLuint texture)
2089{
2090 // Simple pass-through to State's detachTexture method, as textures do not require
2091 // allocation map management either here or in the resource manager at detach time.
2092 // Zero textures are held by the Context, and we don't attempt to request them from
2093 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002094 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002095}
2096
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002097void Context::detachBuffer(GLuint buffer)
2098{
Yuly Novikov5807a532015-12-03 13:01:22 -05002099 // Simple pass-through to State's detachBuffer method, since
2100 // only buffer attachments to container objects that are bound to the current context
2101 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002102
Yuly Novikov5807a532015-12-03 13:01:22 -05002103 // [OpenGL ES 3.2] section 5.1.2 page 45:
2104 // Attachments to unbound container objects, such as
2105 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2106 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002107 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002108}
2109
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002110void Context::detachFramebuffer(GLuint framebuffer)
2111{
Shannon Woods53a94a82014-06-24 15:20:36 -04002112 // Framebuffer detachment is handled by Context, because 0 is a valid
2113 // Framebuffer object, and a pointer to it must be passed from Context
2114 // to State at binding time.
2115
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002116 // [OpenGL ES 2.0.24] section 4.4 page 107:
2117 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2118 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2119
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002120 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002121 {
2122 bindReadFramebuffer(0);
2123 }
2124
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002125 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126 {
2127 bindDrawFramebuffer(0);
2128 }
2129}
2130
2131void Context::detachRenderbuffer(GLuint renderbuffer)
2132{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002133 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002134}
2135
Jamie Madill57a89722013-07-02 11:57:03 -04002136void Context::detachVertexArray(GLuint vertexArray)
2137{
Jamie Madill77a72f62015-04-14 11:18:32 -04002138 // Vertex array detachment is handled by Context, because 0 is a valid
2139 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002140 // binding time.
2141
Jamie Madill57a89722013-07-02 11:57:03 -04002142 // [OpenGL ES 3.0.2] section 2.10 page 43:
2143 // If a vertex array object that is currently bound is deleted, the binding
2144 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002146 {
2147 bindVertexArray(0);
2148 }
2149}
2150
Geoff Langc8058452014-02-03 12:04:11 -05002151void Context::detachTransformFeedback(GLuint transformFeedback)
2152{
Corentin Walleza2257da2016-04-19 16:43:12 -04002153 // Transform feedback detachment is handled by Context, because 0 is a valid
2154 // transform feedback, and a pointer to it must be passed from Context to State at
2155 // binding time.
2156
2157 // The OpenGL specification doesn't mention what should happen when the currently bound
2158 // transform feedback object is deleted. Since it is a container object, we treat it like
2159 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002160 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002161 {
2162 bindTransformFeedback(0);
2163 }
Geoff Langc8058452014-02-03 12:04:11 -05002164}
2165
Jamie Madilldc356042013-07-19 16:36:57 -04002166void Context::detachSampler(GLuint sampler)
2167{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002168 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002169}
2170
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002171void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002174}
2175
Jamie Madille29d1672013-07-19 16:36:57 -04002176void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2177{
Jamie Madill901b3792016-05-26 09:20:40 -04002178 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002179
2180 Sampler *samplerObject = getSampler(sampler);
2181 ASSERT(samplerObject);
2182
Geoff Lang69cce582015-09-17 13:20:36 -04002183 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002184 switch (pname)
2185 {
Geoff Lang69cce582015-09-17 13:20:36 -04002186 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2187 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2188 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2189 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2190 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2191 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
2192 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2193 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2194 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
2195 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
2196 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002197 }
Geoff Lang69cce582015-09-17 13:20:36 -04002198 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002199}
2200
2201void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2202{
Jamie Madill901b3792016-05-26 09:20:40 -04002203 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04002204
2205 Sampler *samplerObject = getSampler(sampler);
2206 ASSERT(samplerObject);
2207
Geoff Lang69cce582015-09-17 13:20:36 -04002208 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04002209 switch (pname)
2210 {
Geoff Lang69cce582015-09-17 13:20:36 -04002211 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2212 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2213 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2214 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2215 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
2216 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
2217 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2218 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
2219 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
2220 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
2221 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002222 }
Geoff Lang69cce582015-09-17 13:20:36 -04002223 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04002224}
2225
Jamie Madill9675b802013-07-19 16:36:59 -04002226GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2227{
Jamie Madill901b3792016-05-26 09:20:40 -04002228 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002229
2230 Sampler *samplerObject = getSampler(sampler);
2231 ASSERT(samplerObject);
2232
Geoff Lang69cce582015-09-17 13:20:36 -04002233 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002234 switch (pname)
2235 {
Geoff Lang69cce582015-09-17 13:20:36 -04002236 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2237 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2238 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2239 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2240 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2241 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02002242 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
2243 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04002244 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
2245 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
2246 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002247 }
Geoff Lang69cce582015-09-17 13:20:36 -04002248 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002249}
2250
2251GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2252{
Jamie Madill901b3792016-05-26 09:20:40 -04002253 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04002254
2255 Sampler *samplerObject = getSampler(sampler);
2256 ASSERT(samplerObject);
2257
Geoff Lang69cce582015-09-17 13:20:36 -04002258 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04002259 switch (pname)
2260 {
Geoff Lang69cce582015-09-17 13:20:36 -04002261 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2262 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2263 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2264 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2265 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2266 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
2267 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2268 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2269 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2270 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2271 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002272 }
Geoff Lang69cce582015-09-17 13:20:36 -04002273 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002274}
2275
Olli Etuahof0fee072016-03-30 15:11:58 +03002276void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2277{
2278 gl::Program *programObject = getProgram(program);
2279 ASSERT(programObject != nullptr);
2280
2281 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2282 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2283}
2284
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002285void Context::initRendererString()
2286{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002287 std::ostringstream rendererString;
2288 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002289 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002290 rendererString << ")";
2291
Geoff Langcec35902014-04-16 10:52:36 -04002292 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002293}
2294
Geoff Langc0b9ef42014-07-02 10:02:37 -04002295const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002296{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002297 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002298}
2299
Geoff Langcec35902014-04-16 10:52:36 -04002300void Context::initExtensionStrings()
2301{
Geoff Lang493daf52014-07-03 13:38:44 -04002302 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002303
Geoff Langc0b9ef42014-07-02 10:02:37 -04002304 std::ostringstream combinedStringStream;
2305 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2306 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002307}
2308
Geoff Langc0b9ef42014-07-02 10:02:37 -04002309const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002310{
2311 return mExtensionString;
2312}
2313
Geoff Langc0b9ef42014-07-02 10:02:37 -04002314const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002315{
2316 return mExtensionStrings[idx];
2317}
2318
2319size_t Context::getExtensionStringCount() const
2320{
2321 return mExtensionStrings.size();
2322}
2323
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002324void Context::beginTransformFeedback(GLenum primitiveMode)
2325{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002326 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002327 ASSERT(transformFeedback != nullptr);
2328 ASSERT(!transformFeedback->isPaused());
2329
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002330 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002331}
2332
2333bool Context::hasActiveTransformFeedback(GLuint program) const
2334{
2335 for (auto pair : mTransformFeedbackMap)
2336 {
2337 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2338 {
2339 return true;
2340 }
2341 }
2342 return false;
2343}
2344
Jamie Madill00ed7a12016-05-19 13:13:38 -04002345void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002346{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002347 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002348
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002349 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002350
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002351 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002352
Martin Radev1be913c2016-07-11 17:59:16 +03002353 if (mClientMajorVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002354 {
2355 // Disable ES3+ extensions
2356 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002357 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002358 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002359 }
2360
Martin Radev1be913c2016-07-11 17:59:16 +03002361 if (mClientMajorVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002362 {
2363 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2364 //mExtensions.sRGB = false;
2365 }
2366
Jamie Madill00ed7a12016-05-19 13:13:38 -04002367 // Some extensions are always available because they are implemented in the GL layer.
2368 mExtensions.bindUniformLocation = true;
2369 mExtensions.vertexArrayObject = true;
2370
2371 // Enable the no error extension if the context was created with the flag.
2372 mExtensions.noError = mSkipValidation;
2373
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 // Explicitly enable GL_KHR_debug
2375 mExtensions.debug = true;
2376 mExtensions.maxDebugMessageLength = 1024;
2377 mExtensions.maxDebugLoggedMessages = 1024;
2378 mExtensions.maxDebugGroupStackDepth = 1024;
2379 mExtensions.maxLabelLength = 1024;
2380
Geoff Lang301d1612014-07-09 10:34:37 -04002381 // Apply implementation limits
2382 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002383 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2384 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2385
2386 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002387
Geoff Lang900013c2014-07-07 11:32:19 -04002388 mCaps.compressedTextureFormats.clear();
2389
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002390 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002391 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2392 {
2393 GLenum format = i->first;
2394 TextureCaps formatCaps = i->second;
2395
Geoff Lang5d601382014-07-22 15:14:06 -04002396 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002397
Geoff Lang0d8b7242015-09-09 14:56:53 -04002398 // Update the format caps based on the client version and extensions.
2399 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2400 // ES3.
2401 formatCaps.texturable =
Martin Radev1be913c2016-07-11 17:59:16 +03002402 formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002403 formatCaps.renderable =
Martin Radev1be913c2016-07-11 17:59:16 +03002404 formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002405 formatCaps.filterable =
Martin Radev1be913c2016-07-11 17:59:16 +03002406 formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002407
2408 // OpenGL ES does not support multisampling with integer formats
2409 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002410 {
Geoff Langd87878e2014-09-19 15:42:59 -04002411 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002412 }
Geoff Langd87878e2014-09-19 15:42:59 -04002413
2414 if (formatCaps.texturable && formatInfo.compressed)
2415 {
2416 mCaps.compressedTextureFormats.push_back(format);
2417 }
2418
2419 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002420 }
2421}
2422
Jamie Madill1b94d432015-08-07 13:23:23 -04002423void Context::syncRendererState()
2424{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002425 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2426 mImplementation->syncState(mGLState, dirtyBits);
2427 mGLState.clearDirtyBits();
2428 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002429}
2430
Jamie Madillad9f24e2016-02-12 09:27:24 -05002431void Context::syncRendererState(const State::DirtyBits &bitMask,
2432 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002433{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002434 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2435 mImplementation->syncState(mGLState, dirtyBits);
2436 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002437
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002438 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002439}
Jamie Madillc29968b2016-01-20 11:17:23 -05002440
2441void Context::blitFramebuffer(GLint srcX0,
2442 GLint srcY0,
2443 GLint srcX1,
2444 GLint srcY1,
2445 GLint dstX0,
2446 GLint dstY0,
2447 GLint dstX1,
2448 GLint dstY1,
2449 GLbitfield mask,
2450 GLenum filter)
2451{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002452 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002453 ASSERT(drawFramebuffer);
2454
2455 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2456 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2457
Jamie Madillad9f24e2016-02-12 09:27:24 -05002458 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002459
Jamie Madill8415b5f2016-04-26 13:41:39 -04002460 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002461}
Jamie Madillc29968b2016-01-20 11:17:23 -05002462
2463void Context::clear(GLbitfield mask)
2464{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002465 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002466 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002467}
2468
2469void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2470{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002471 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002472 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2473 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002474}
2475
2476void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2477{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002478 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002479 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2480 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002481}
2482
2483void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2484{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002485 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002486 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2487 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002488}
2489
2490void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2491{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002492 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 ASSERT(framebufferObject);
2494
2495 // If a buffer is not present, the clear has no effect
2496 if (framebufferObject->getDepthbuffer() == nullptr &&
2497 framebufferObject->getStencilbuffer() == nullptr)
2498 {
2499 return;
2500 }
2501
Jamie Madillad9f24e2016-02-12 09:27:24 -05002502 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002503 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2504 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002505}
2506
2507void Context::readPixels(GLint x,
2508 GLint y,
2509 GLsizei width,
2510 GLsizei height,
2511 GLenum format,
2512 GLenum type,
2513 GLvoid *pixels)
2514{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002515 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002516
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002517 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002518 ASSERT(framebufferObject);
2519
2520 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002521 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002522}
2523
2524void Context::copyTexImage2D(GLenum target,
2525 GLint level,
2526 GLenum internalformat,
2527 GLint x,
2528 GLint y,
2529 GLsizei width,
2530 GLsizei height,
2531 GLint border)
2532{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002533 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002534 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002535
Jamie Madillc29968b2016-01-20 11:17:23 -05002536 Rectangle sourceArea(x, y, width, height);
2537
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002538 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002539 Texture *texture =
2540 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002541 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002542}
2543
2544void Context::copyTexSubImage2D(GLenum target,
2545 GLint level,
2546 GLint xoffset,
2547 GLint yoffset,
2548 GLint x,
2549 GLint y,
2550 GLsizei width,
2551 GLsizei height)
2552{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002553 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002554 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002555
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 Offset destOffset(xoffset, yoffset, 0);
2557 Rectangle sourceArea(x, y, width, height);
2558
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002559 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 Texture *texture =
2561 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002562 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002563}
2564
2565void Context::copyTexSubImage3D(GLenum target,
2566 GLint level,
2567 GLint xoffset,
2568 GLint yoffset,
2569 GLint zoffset,
2570 GLint x,
2571 GLint y,
2572 GLsizei width,
2573 GLsizei height)
2574{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002575 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002576 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002577
Jamie Madillc29968b2016-01-20 11:17:23 -05002578 Offset destOffset(xoffset, yoffset, zoffset);
2579 Rectangle sourceArea(x, y, width, height);
2580
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002581 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002582 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002583 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002584}
2585
2586void Context::framebufferTexture2D(GLenum target,
2587 GLenum attachment,
2588 GLenum textarget,
2589 GLuint texture,
2590 GLint level)
2591{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002592 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 ASSERT(framebuffer);
2594
2595 if (texture != 0)
2596 {
2597 Texture *textureObj = getTexture(texture);
2598
2599 ImageIndex index = ImageIndex::MakeInvalid();
2600
2601 if (textarget == GL_TEXTURE_2D)
2602 {
2603 index = ImageIndex::Make2D(level);
2604 }
2605 else
2606 {
2607 ASSERT(IsCubeMapTextureTarget(textarget));
2608 index = ImageIndex::MakeCube(textarget, level);
2609 }
2610
2611 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2612 }
2613 else
2614 {
2615 framebuffer->resetAttachment(attachment);
2616 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002617
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002618 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002619}
2620
2621void Context::framebufferRenderbuffer(GLenum target,
2622 GLenum attachment,
2623 GLenum renderbuffertarget,
2624 GLuint renderbuffer)
2625{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002626 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002627 ASSERT(framebuffer);
2628
2629 if (renderbuffer != 0)
2630 {
2631 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2632 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2633 renderbufferObject);
2634 }
2635 else
2636 {
2637 framebuffer->resetAttachment(attachment);
2638 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002639
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002640 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002641}
2642
2643void Context::framebufferTextureLayer(GLenum target,
2644 GLenum attachment,
2645 GLuint texture,
2646 GLint level,
2647 GLint layer)
2648{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002649 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 ASSERT(framebuffer);
2651
2652 if (texture != 0)
2653 {
2654 Texture *textureObject = getTexture(texture);
2655
2656 ImageIndex index = ImageIndex::MakeInvalid();
2657
2658 if (textureObject->getTarget() == GL_TEXTURE_3D)
2659 {
2660 index = ImageIndex::Make3D(level, layer);
2661 }
2662 else
2663 {
2664 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2665 index = ImageIndex::Make2DArray(level, layer);
2666 }
2667
2668 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2669 }
2670 else
2671 {
2672 framebuffer->resetAttachment(attachment);
2673 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002674
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002675 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002676}
2677
2678void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2679{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002680 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002681 ASSERT(framebuffer);
2682 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002683 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684}
2685
2686void Context::readBuffer(GLenum mode)
2687{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002688 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002689 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002690 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002691}
2692
2693void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2694{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002695 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002696 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002697
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002698 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002699 ASSERT(framebuffer);
2700
2701 // The specification isn't clear what should be done when the framebuffer isn't complete.
2702 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002703 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002704}
2705
2706void Context::invalidateFramebuffer(GLenum target,
2707 GLsizei numAttachments,
2708 const GLenum *attachments)
2709{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002710 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002711 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002712
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002713 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002714 ASSERT(framebuffer);
2715
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002716 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002717 {
Jamie Madill437fa652016-05-03 15:13:24 -04002718 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 }
Jamie Madill437fa652016-05-03 15:13:24 -04002720
2721 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002722}
2723
2724void Context::invalidateSubFramebuffer(GLenum target,
2725 GLsizei numAttachments,
2726 const GLenum *attachments,
2727 GLint x,
2728 GLint y,
2729 GLsizei width,
2730 GLsizei height)
2731{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002732 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002733 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002734
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002735 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002736 ASSERT(framebuffer);
2737
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002738 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002739 {
Jamie Madill437fa652016-05-03 15:13:24 -04002740 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002741 }
Jamie Madill437fa652016-05-03 15:13:24 -04002742
2743 Rectangle area(x, y, width, height);
2744 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002745}
2746
Jamie Madill73a84962016-02-12 09:27:23 -05002747void Context::texImage2D(GLenum target,
2748 GLint level,
2749 GLint internalformat,
2750 GLsizei width,
2751 GLsizei height,
2752 GLint border,
2753 GLenum format,
2754 GLenum type,
2755 const GLvoid *pixels)
2756{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002757 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002758
2759 Extents size(width, height, 1);
2760 Texture *texture =
2761 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002762 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002763 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002764}
2765
2766void Context::texImage3D(GLenum target,
2767 GLint level,
2768 GLint internalformat,
2769 GLsizei width,
2770 GLsizei height,
2771 GLsizei depth,
2772 GLint border,
2773 GLenum format,
2774 GLenum type,
2775 const GLvoid *pixels)
2776{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002777 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002778
2779 Extents size(width, height, depth);
2780 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002781 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002782 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002783}
2784
2785void Context::texSubImage2D(GLenum target,
2786 GLint level,
2787 GLint xoffset,
2788 GLint yoffset,
2789 GLsizei width,
2790 GLsizei height,
2791 GLenum format,
2792 GLenum type,
2793 const GLvoid *pixels)
2794{
2795 // Zero sized uploads are valid but no-ops
2796 if (width == 0 || height == 0)
2797 {
2798 return;
2799 }
2800
Jamie Madillad9f24e2016-02-12 09:27:24 -05002801 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002802
2803 Box area(xoffset, yoffset, 0, width, height, 1);
2804 Texture *texture =
2805 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002806 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002807 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002808}
2809
2810void Context::texSubImage3D(GLenum target,
2811 GLint level,
2812 GLint xoffset,
2813 GLint yoffset,
2814 GLint zoffset,
2815 GLsizei width,
2816 GLsizei height,
2817 GLsizei depth,
2818 GLenum format,
2819 GLenum type,
2820 const GLvoid *pixels)
2821{
2822 // Zero sized uploads are valid but no-ops
2823 if (width == 0 || height == 0 || depth == 0)
2824 {
2825 return;
2826 }
2827
Jamie Madillad9f24e2016-02-12 09:27:24 -05002828 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002829
2830 Box area(xoffset, yoffset, zoffset, width, height, depth);
2831 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002832 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002833 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002834}
2835
2836void Context::compressedTexImage2D(GLenum target,
2837 GLint level,
2838 GLenum internalformat,
2839 GLsizei width,
2840 GLsizei height,
2841 GLint border,
2842 GLsizei imageSize,
2843 const GLvoid *data)
2844{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002845 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002846
2847 Extents size(width, height, 1);
2848 Texture *texture =
2849 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2851 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002852 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002853}
2854
2855void Context::compressedTexImage3D(GLenum target,
2856 GLint level,
2857 GLenum internalformat,
2858 GLsizei width,
2859 GLsizei height,
2860 GLsizei depth,
2861 GLint border,
2862 GLsizei imageSize,
2863 const GLvoid *data)
2864{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002865 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002866
2867 Extents size(width, height, depth);
2868 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002869 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2870 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002871 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002872}
2873
2874void Context::compressedTexSubImage2D(GLenum target,
2875 GLint level,
2876 GLint xoffset,
2877 GLint yoffset,
2878 GLsizei width,
2879 GLsizei height,
2880 GLenum format,
2881 GLsizei imageSize,
2882 const GLvoid *data)
2883{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002884 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002885
2886 Box area(xoffset, yoffset, 0, width, height, 1);
2887 Texture *texture =
2888 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002889 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2890 format, imageSize,
2891 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002892}
2893
2894void Context::compressedTexSubImage3D(GLenum target,
2895 GLint level,
2896 GLint xoffset,
2897 GLint yoffset,
2898 GLint zoffset,
2899 GLsizei width,
2900 GLsizei height,
2901 GLsizei depth,
2902 GLenum format,
2903 GLsizei imageSize,
2904 const GLvoid *data)
2905{
2906 // Zero sized uploads are valid but no-ops
2907 if (width == 0 || height == 0)
2908 {
2909 return;
2910 }
2911
Jamie Madillad9f24e2016-02-12 09:27:24 -05002912 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002913
2914 Box area(xoffset, yoffset, zoffset, width, height, depth);
2915 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002916 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2917 format, imageSize,
2918 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002919}
2920
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002921void Context::generateMipmap(GLenum target)
2922{
2923 Texture *texture = getTargetTexture(target);
2924 handleError(texture->generateMipmap());
2925}
2926
Geoff Lang97073d12016-04-20 10:42:34 -07002927void Context::copyTextureCHROMIUM(GLuint sourceId,
2928 GLuint destId,
2929 GLint internalFormat,
2930 GLenum destType,
2931 GLboolean unpackFlipY,
2932 GLboolean unpackPremultiplyAlpha,
2933 GLboolean unpackUnmultiplyAlpha)
2934{
2935 syncStateForTexImage();
2936
2937 gl::Texture *sourceTexture = getTexture(sourceId);
2938 gl::Texture *destTexture = getTexture(destId);
2939 handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE,
2940 unpackPremultiplyAlpha == GL_TRUE,
2941 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2942}
2943
2944void Context::copySubTextureCHROMIUM(GLuint sourceId,
2945 GLuint destId,
2946 GLint xoffset,
2947 GLint yoffset,
2948 GLint x,
2949 GLint y,
2950 GLsizei width,
2951 GLsizei height,
2952 GLboolean unpackFlipY,
2953 GLboolean unpackPremultiplyAlpha,
2954 GLboolean unpackUnmultiplyAlpha)
2955{
2956 // Zero sized copies are valid but no-ops
2957 if (width == 0 || height == 0)
2958 {
2959 return;
2960 }
2961
2962 syncStateForTexImage();
2963
2964 gl::Texture *sourceTexture = getTexture(sourceId);
2965 gl::Texture *destTexture = getTexture(destId);
2966 Offset offset(xoffset, yoffset, 0);
2967 Rectangle area(x, y, width, height);
2968 handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE,
2969 unpackPremultiplyAlpha == GL_TRUE,
2970 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
2971}
2972
Olli Etuaho4f667482016-03-30 15:56:35 +03002973void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2974{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002975 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002976 ASSERT(buffer);
2977
2978 if (!buffer->isMapped())
2979 {
2980 *params = nullptr;
2981 }
2982 else
2983 {
2984 *params = buffer->getMapPointer();
2985 }
2986}
2987
2988GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2989{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002990 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002991 ASSERT(buffer);
2992
2993 Error error = buffer->map(access);
2994 if (error.isError())
2995 {
Jamie Madill437fa652016-05-03 15:13:24 -04002996 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002997 return nullptr;
2998 }
2999
3000 return buffer->getMapPointer();
3001}
3002
3003GLboolean Context::unmapBuffer(GLenum target)
3004{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003005 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003006 ASSERT(buffer);
3007
3008 GLboolean result;
3009 Error error = buffer->unmap(&result);
3010 if (error.isError())
3011 {
Jamie Madill437fa652016-05-03 15:13:24 -04003012 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003013 return GL_FALSE;
3014 }
3015
3016 return result;
3017}
3018
3019GLvoid *Context::mapBufferRange(GLenum target,
3020 GLintptr offset,
3021 GLsizeiptr length,
3022 GLbitfield access)
3023{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003024 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003025 ASSERT(buffer);
3026
3027 Error error = buffer->mapRange(offset, length, access);
3028 if (error.isError())
3029 {
Jamie Madill437fa652016-05-03 15:13:24 -04003030 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003031 return nullptr;
3032 }
3033
3034 return buffer->getMapPointer();
3035}
3036
3037void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3038{
3039 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3040}
3041
Jamie Madillad9f24e2016-02-12 09:27:24 -05003042void Context::syncStateForReadPixels()
3043{
3044 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3045}
3046
3047void Context::syncStateForTexImage()
3048{
3049 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3050}
3051
3052void Context::syncStateForClear()
3053{
3054 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3055}
3056
3057void Context::syncStateForBlit()
3058{
3059 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3060}
3061
Jamie Madillc20ab272016-06-09 07:20:46 -07003062void Context::activeTexture(GLenum texture)
3063{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003064 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003065}
3066
3067void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3068{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003069 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003070}
3071
3072void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3073{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003074 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003075}
3076
3077void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3078{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003079 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003080}
3081
3082void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3083{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003084 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003085}
3086
3087void Context::clearDepthf(GLclampf depth)
3088{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003089 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003090}
3091
3092void Context::clearStencil(GLint s)
3093{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003094 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003095}
3096
3097void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3098{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003099 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003100}
3101
3102void Context::cullFace(GLenum mode)
3103{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003104 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003105}
3106
3107void Context::depthFunc(GLenum func)
3108{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003109 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003110}
3111
3112void Context::depthMask(GLboolean flag)
3113{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003114 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003115}
3116
3117void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3118{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003119 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003120}
3121
3122void Context::disable(GLenum cap)
3123{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003124 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003125}
3126
3127void Context::disableVertexAttribArray(GLuint index)
3128{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003129 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003130}
3131
3132void Context::enable(GLenum cap)
3133{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003134 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003135}
3136
3137void Context::enableVertexAttribArray(GLuint index)
3138{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003139 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003140}
3141
3142void Context::frontFace(GLenum mode)
3143{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003144 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003145}
3146
3147void Context::hint(GLenum target, GLenum mode)
3148{
3149 switch (target)
3150 {
3151 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003152 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003153 break;
3154
3155 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003156 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003157 break;
3158
3159 default:
3160 UNREACHABLE();
3161 return;
3162 }
3163}
3164
3165void Context::lineWidth(GLfloat width)
3166{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003167 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003168}
3169
3170void Context::pixelStorei(GLenum pname, GLint param)
3171{
3172 switch (pname)
3173 {
3174 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003175 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003176 break;
3177
3178 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003179 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003180 break;
3181
3182 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003183 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003184 break;
3185
3186 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003187 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003188 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003189 break;
3190
3191 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003192 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003193 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003194 break;
3195
3196 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003197 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003198 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003199 break;
3200
3201 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003202 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003203 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003204 break;
3205
3206 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003207 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003208 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003209 break;
3210
3211 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003212 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003213 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003214 break;
3215
3216 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003217 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003218 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003219 break;
3220
3221 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003222 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003223 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003224 break;
3225
3226 default:
3227 UNREACHABLE();
3228 return;
3229 }
3230}
3231
3232void Context::polygonOffset(GLfloat factor, GLfloat units)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::sampleCoverage(GLclampf value, GLboolean invert)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3248{
3249 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3250 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003251 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003252 }
3253
3254 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3255 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003256 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003257 }
3258}
3259
3260void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3261{
3262 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3263 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265 }
3266
3267 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3268 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003270 }
3271}
3272
3273void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3274{
3275 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3276 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003277 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003278 }
3279
3280 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3281 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003282 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003283 }
3284}
3285
3286void Context::vertexAttrib1f(GLuint index, GLfloat x)
3287{
3288 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003289 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003290}
3291
3292void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3293{
3294 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003295 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003296}
3297
3298void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3299{
3300 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003301 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003302}
3303
3304void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3305{
3306 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003307 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003308}
3309
3310void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3311{
3312 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003313 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003314}
3315
3316void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3317{
3318 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003319 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003320}
3321
3322void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3323{
3324 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003325 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003326}
3327
3328void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3329{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003330 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003331}
3332
3333void Context::vertexAttribPointer(GLuint index,
3334 GLint size,
3335 GLenum type,
3336 GLboolean normalized,
3337 GLsizei stride,
3338 const GLvoid *ptr)
3339{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003340 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3341 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003342}
3343
3344void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3345{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003346 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003347}
3348
3349void Context::vertexAttribIPointer(GLuint index,
3350 GLint size,
3351 GLenum type,
3352 GLsizei stride,
3353 const GLvoid *pointer)
3354{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003355 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3356 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003357}
3358
3359void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3360{
3361 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003362 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003363}
3364
3365void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3366{
3367 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003368 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003369}
3370
3371void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3372{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003373 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003374}
3375
3376void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003378 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003379}
3380
3381void Context::debugMessageControl(GLenum source,
3382 GLenum type,
3383 GLenum severity,
3384 GLsizei count,
3385 const GLuint *ids,
3386 GLboolean enabled)
3387{
3388 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003389 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3390 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003391}
3392
3393void Context::debugMessageInsert(GLenum source,
3394 GLenum type,
3395 GLuint id,
3396 GLenum severity,
3397 GLsizei length,
3398 const GLchar *buf)
3399{
3400 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003401 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003402}
3403
3404void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3405{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003406 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003407}
3408
3409GLuint Context::getDebugMessageLog(GLuint count,
3410 GLsizei bufSize,
3411 GLenum *sources,
3412 GLenum *types,
3413 GLuint *ids,
3414 GLenum *severities,
3415 GLsizei *lengths,
3416 GLchar *messageLog)
3417{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003418 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3419 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003420}
3421
3422void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3423{
3424 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003425 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003426}
3427
3428void Context::popDebugGroup()
3429{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
Jamie Madillc29968b2016-01-20 11:17:23 -05003433} // namespace gl