blob: 2c9b4f4f917c8ff0666047f30afbfaf3a9a92261 [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 Langc339c4e2016-11-29 10:37:36 -050020#include "common/version.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050021#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050022#include "libANGLE/Compiler.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Kenneth Russellf2f6f652016-10-05 19:53:23 -070038#include "libANGLE/Workarounds.h"
Jamie Madill437fa652016-05-03 15:13:24 -040039#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040040#include "libANGLE/renderer/EGLImplFactory.h"
Martin Radev66fb8202016-07-28 11:45:20 +030041#include "libANGLE/queryconversions.h"
Geoff Langc1984ed2016-10-07 12:41:00 -040042#include "libANGLE/queryutils.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000043
Geoff Langf6db0982015-08-25 13:04:00 -040044namespace
45{
46
Ian Ewell3ffd78b2016-01-22 16:09:42 -050047template <typename T>
Geoff Lang4ddf5af2016-12-01 14:30:44 -050048std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030049 GLsizei numPaths,
50 const void *paths,
51 GLuint pathBase)
52{
53 std::vector<gl::Path *> ret;
54 ret.reserve(numPaths);
55
56 const auto *nameArray = static_cast<const T *>(paths);
57
58 for (GLsizei i = 0; i < numPaths; ++i)
59 {
60 const GLuint pathName = nameArray[i] + pathBase;
61
62 ret.push_back(resourceManager.getPath(pathName));
63 }
64
65 return ret;
66}
67
Geoff Lang4ddf5af2016-12-01 14:30:44 -050068std::vector<gl::Path *> GatherPaths(gl::PathManager &resourceManager,
Sami Väisänend59ca052016-06-21 16:10:00 +030069 GLsizei numPaths,
70 GLenum pathNameType,
71 const void *paths,
72 GLuint pathBase)
73{
74 switch (pathNameType)
75 {
76 case GL_UNSIGNED_BYTE:
77 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_BYTE:
80 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_UNSIGNED_SHORT:
83 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_SHORT:
86 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_UNSIGNED_INT:
89 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
90
91 case GL_INT:
92 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
93 }
94
95 UNREACHABLE();
96 return std::vector<gl::Path *>();
97}
98
99template <typename T>
Geoff Lang2186c382016-10-14 10:54:54 -0400100gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500101{
Geoff Lang2186c382016-10-14 10:54:54 -0400102 ASSERT(query != nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500103
104 switch (pname)
105 {
106 case GL_QUERY_RESULT_EXT:
Geoff Lang2186c382016-10-14 10:54:54 -0400107 return query->getResult(params);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500108 case GL_QUERY_RESULT_AVAILABLE_EXT:
109 {
110 bool available;
Geoff Lang2186c382016-10-14 10:54:54 -0400111 gl::Error error = query->isResultAvailable(&available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500112 if (!error.isError())
113 {
Geoff Lang2186c382016-10-14 10:54:54 -0400114 *params = gl::ConvertFromGLboolean<T>(available);
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500115 }
116 return error;
117 }
118 default:
119 UNREACHABLE();
120 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
121 }
122}
123
Geoff Langf6db0982015-08-25 13:04:00 -0400124void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
125{
Geoff Lang1a683462015-09-29 15:09:59 -0400126 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400127 {
128 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
129 tfBufferIndex++)
130 {
131 const OffsetBindingPointer<gl::Buffer> &buffer =
132 transformFeedback->getIndexedBuffer(tfBufferIndex);
133 if (buffer.get() != nullptr)
134 {
135 buffer->onTransformFeedback();
136 }
137 }
138 }
139}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140
141// Attribute map queries.
Martin Radev1be913c2016-07-11 17:59:16 +0300142EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400144 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500145}
146
Martin Radev1be913c2016-07-11 17:59:16 +0300147EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
148{
149 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
150}
151
Geoff Langeb66a6e2016-10-31 13:06:12 -0400152gl::Version GetClientVersion(const egl::AttributeMap &attribs)
153{
154 return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
155}
156
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500157GLenum GetResetStrategy(const egl::AttributeMap &attribs)
158{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400159 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
160 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500161 switch (attrib)
162 {
163 case EGL_NO_RESET_NOTIFICATION:
164 return GL_NO_RESET_NOTIFICATION_EXT;
165 case EGL_LOSE_CONTEXT_ON_RESET:
166 return GL_LOSE_CONTEXT_ON_RESET_EXT;
167 default:
168 UNREACHABLE();
169 return GL_NONE;
170 }
171}
172
173bool GetRobustAccess(const egl::AttributeMap &attribs)
174{
Geoff Lang077f20a2016-11-01 10:08:02 -0400175 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) ||
176 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) !=
177 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500178}
179
180bool GetDebug(const egl::AttributeMap &attribs)
181{
Geoff Lang077f20a2016-11-01 10:08:02 -0400182 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
183 ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184}
185
186bool GetNoError(const egl::AttributeMap &attribs)
187{
188 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
189}
190
Geoff Langc287ea62016-09-16 14:46:51 -0400191bool GetWebGLContext(const egl::AttributeMap &attribs)
192{
193 return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
194}
195
Geoff Langf41a7152016-09-19 15:11:17 -0400196bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
197{
198 return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
199}
200
Geoff Langfeb8c682017-02-13 16:07:35 -0500201bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
202{
203 return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
204}
205
Martin Radev9d901792016-07-15 15:58:58 +0300206std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
207{
208 std::string labelName;
209 if (label != nullptr)
210 {
211 size_t labelLength = length < 0 ? strlen(label) : length;
212 labelName = std::string(label, labelLength);
213 }
214 return labelName;
215}
216
217void GetObjectLabelBase(const std::string &objectLabel,
218 GLsizei bufSize,
219 GLsizei *length,
220 GLchar *label)
221{
222 size_t writeLength = objectLabel.length();
223 if (label != nullptr && bufSize > 0)
224 {
225 writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
226 std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
227 label[writeLength] = '\0';
228 }
229
230 if (length != nullptr)
231 {
232 *length = static_cast<GLsizei>(writeLength);
233 }
234}
235
Geoff Langf6db0982015-08-25 13:04:00 -0400236} // anonymous namespace
237
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000238namespace gl
239{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000240
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400241Context::Context(rx::EGLImplFactory *implFactory,
242 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400243 const Context *shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500244 TextureManager *shareTextures,
Corentin Wallezc295e512017-01-27 17:47:50 -0500245 const egl::AttributeMap &attribs,
246 const egl::DisplayExtensions &displayExtensions)
Martin Radev1be913c2016-07-11 17:59:16 +0300247
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500248 : ValidationContext(shareContext,
Geoff Langce02f082017-02-06 16:46:21 -0500249 shareTextures,
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500250 GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700251 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500252 mCaps,
253 mTextureCaps,
254 mExtensions,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500255 mLimitations,
256 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700257 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500258 mCompiler(nullptr),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400259 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500260 mClientType(EGL_OPENGL_ES_API),
261 mHasBeenCurrent(false),
262 mContextLost(false),
263 mResetStatus(GL_NO_ERROR),
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700264 mContextLostForced(false),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500265 mResetStrategy(GetResetStrategy(attribs)),
266 mRobustAccess(GetRobustAccess(attribs)),
Corentin Wallezccab69d2017-01-27 16:57:15 -0500267 mCurrentSurface(nullptr),
268 mSurfacelessFramebuffer(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000269{
Geoff Lang077f20a2016-11-01 10:08:02 -0400270 if (mRobustAccess)
271 {
272 UNIMPLEMENTED();
273 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000274
Corentin Wallezc295e512017-01-27 17:47:50 -0500275 initCaps(GetWebGLContext(attribs), displayExtensions);
Kenneth Russellf2f6f652016-10-05 19:53:23 -0700276 initWorkarounds();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400277
Geoff Langeb66a6e2016-10-31 13:06:12 -0400278 mGLState.initialize(mCaps, mExtensions, getClientVersion(), GetDebug(attribs),
Geoff Langfeb8c682017-02-13 16:07:35 -0500279 GetBindGeneratesResource(attribs), GetClientArraysEnabled(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100280
Shannon Woods53a94a82014-06-24 15:20:36 -0400281 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400282
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000283 // [OpenGL ES 2.0.24] section 3.7 page 83:
284 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
285 // and cube map texture state vectors respectively associated with them.
286 // In order that access to these initial textures not be lost, they are treated as texture
287 // objects all of whose names are 0.
288
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400289 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500290 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500291
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400292 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500293 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400294
Geoff Langeb66a6e2016-10-31 13:06:12 -0400295 if (getClientVersion() >= Version(3, 0))
Geoff Lang76b10c92014-09-05 16:28:14 -0400296 {
297 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400298 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500299 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400300
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400301 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500302 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400303 }
Geoff Lang3b573612016-10-31 14:08:10 -0400304 if (getClientVersion() >= Version(3, 1))
305 {
306 Texture *zeroTexture2DMultisample =
307 new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE);
308 mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(zeroTexture2DMultisample);
309 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000310
Ian Ewellbda75592016-04-18 17:25:54 -0400311 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
312 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400313 Texture *zeroTextureExternal =
314 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400315 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
316 }
317
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700318 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500319
Jamie Madill57a89722013-07-02 11:57:03 -0400320 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000321 bindArrayBuffer(0);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800322 bindDrawIndirectBuffer(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000323 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400324
Jamie Madill01a80ee2016-11-07 12:06:18 -0500325 bindRenderbuffer(GL_RENDERBUFFER, 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000327 bindGenericUniformBuffer(0);
Geoff Lang4dc3af02016-11-18 14:09:27 -0500328 for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000329 {
330 bindIndexedUniformBuffer(0, i, 0, -1);
331 }
332
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000333 bindCopyReadBuffer(0);
334 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000335 bindPixelPackBuffer(0);
336 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000337
Geoff Langeb66a6e2016-10-31 13:06:12 -0400338 if (getClientVersion() >= Version(3, 0))
Geoff Lang1a683462015-09-29 15:09:59 -0400339 {
340 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
341 // In the initial state, a default transform feedback object is bound and treated as
342 // a transform feedback object with a name of zero. That object is bound any time
343 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400344 bindTransformFeedback(0);
345 }
Geoff Langc8058452014-02-03 12:04:11 -0500346
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700347 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500348
349 // Initialize dirty bit masks
350 // TODO(jmadill): additional ES3 state
351 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
352 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
353 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
354 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
355 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
356 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400357 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500358 // No dirty objects.
359
360 // Readpixels uses the pack state and read FBO
361 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
362 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
363 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
364 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
365 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400366 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500367 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
368
369 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
370 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
371 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
372 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
373 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
374 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
375 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
376 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
377 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
378 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
379 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
380 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
381
382 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
383 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700384 mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500385 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
386 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400387
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400388 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389}
390
Jamie Madill70ee0f62017-02-06 16:04:20 -0500391void Context::destroy(egl::Display *display)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000392{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500393 mGLState.reset(this);
Geoff Lang21329412014-12-02 20:50:30 +0000394
Corentin Wallez80b24112015-08-25 16:41:57 -0400395 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000396 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400397 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000398 }
399
Corentin Wallez80b24112015-08-25 16:41:57 -0400400 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000401 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400402 if (query.second != nullptr)
403 {
404 query.second->release();
405 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000406 }
407
Corentin Wallez80b24112015-08-25 16:41:57 -0400408 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400409 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400410 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400411 }
412
Corentin Wallez80b24112015-08-25 16:41:57 -0400413 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500414 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500415 if (transformFeedback.second != nullptr)
416 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500417 transformFeedback.second->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500418 }
Geoff Langc8058452014-02-03 12:04:11 -0500419 }
420
Jamie Madilldedd7b92014-11-05 16:30:36 -0500421 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400422 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500423 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400424 }
425 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426
Corentin Wallezccab69d2017-01-27 16:57:15 -0500427 SafeDelete(mSurfacelessFramebuffer);
428
Jamie Madill70ee0f62017-02-06 16:04:20 -0500429 releaseSurface(display);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400430
Geoff Lang492a7e42014-11-05 13:27:06 -0500431 SafeDelete(mCompiler);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500432
433 mState.mBuffers->release(this);
434 mState.mShaderPrograms->release(this);
435 mState.mTextures->release(this);
436 mState.mRenderbuffers->release(this);
437 mState.mSamplers->release(this);
438 mState.mFenceSyncs->release(this);
439 mState.mPaths->release(this);
440 mState.mFramebuffers->release(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000441}
442
Jamie Madill70ee0f62017-02-06 16:04:20 -0500443Context::~Context()
444{
445}
446
447void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000448{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000449 if (!mHasBeenCurrent)
450 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451 initRendererString();
Geoff Langc339c4e2016-11-29 10:37:36 -0500452 initVersionStrings();
Geoff Langcec35902014-04-16 10:52:36 -0400453 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454
Corentin Wallezc295e512017-01-27 17:47:50 -0500455 int width = 0;
456 int height = 0;
457 if (surface != nullptr)
458 {
459 width = surface->getWidth();
460 height = surface->getHeight();
461 }
462
463 mGLState.setViewportParams(0, 0, width, height);
464 mGLState.setScissorParams(0, 0, width, height);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000465
466 mHasBeenCurrent = true;
467 }
468
Jamie Madill1b94d432015-08-07 13:23:23 -0400469 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700470 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400471
Jamie Madill70ee0f62017-02-06 16:04:20 -0500472 releaseSurface(display);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500473
474 Framebuffer *newDefault = nullptr;
475 if (surface != nullptr)
476 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500477 surface->setIsCurrent(display, true);
Corentin Wallezccab69d2017-01-27 16:57:15 -0500478 mCurrentSurface = surface;
479 newDefault = surface->getDefaultFramebuffer();
480 }
481 else
482 {
483 if (mSurfacelessFramebuffer == nullptr)
484 {
485 mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
486 }
487
488 newDefault = mSurfacelessFramebuffer;
489 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000490
Corentin Wallez37c39792015-08-20 14:19:46 -0400491 // Update default framebuffer, the binding of the previous default
492 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400493 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700494 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400495 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700496 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400497 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700498 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400499 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700500 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400501 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500502 mState.mFramebuffers->setDefaultFramebuffer(newDefault);
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400503 }
Ian Ewell292f0052016-02-04 10:37:32 -0500504
505 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700506 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000507}
508
Jamie Madill70ee0f62017-02-06 16:04:20 -0500509void Context::releaseSurface(egl::Display *display)
Jamie Madill77a72f62015-04-14 11:18:32 -0400510{
Corentin Wallez37c39792015-08-20 14:19:46 -0400511 // Remove the default framebuffer
Corentin Wallezc295e512017-01-27 17:47:50 -0500512 Framebuffer *currentDefault = nullptr;
513 if (mCurrentSurface != nullptr)
Corentin Wallez51706ea2015-08-07 14:39:22 -0400514 {
Corentin Wallezc295e512017-01-27 17:47:50 -0500515 currentDefault = mCurrentSurface->getDefaultFramebuffer();
516 }
517 else if (mSurfacelessFramebuffer != nullptr)
518 {
519 currentDefault = mSurfacelessFramebuffer;
Corentin Wallez51706ea2015-08-07 14:39:22 -0400520 }
521
Corentin Wallezc295e512017-01-27 17:47:50 -0500522 if (mGLState.getReadFramebuffer() == currentDefault)
523 {
524 mGLState.setReadFramebufferBinding(nullptr);
525 }
526 if (mGLState.getDrawFramebuffer() == currentDefault)
527 {
528 mGLState.setDrawFramebufferBinding(nullptr);
529 }
530 mState.mFramebuffers->setDefaultFramebuffer(nullptr);
531
532 if (mCurrentSurface)
533 {
Jamie Madill70ee0f62017-02-06 16:04:20 -0500534 mCurrentSurface->setIsCurrent(display, false);
Corentin Wallezc295e512017-01-27 17:47:50 -0500535 mCurrentSurface = nullptr;
536 }
Jamie Madill77a72f62015-04-14 11:18:32 -0400537}
538
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000539GLuint Context::createBuffer()
540{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500541 return mState.mBuffers->createBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000542}
543
544GLuint Context::createProgram()
545{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500546 return mState.mShaderPrograms->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000547}
548
549GLuint Context::createShader(GLenum type)
550{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500551 return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552}
553
554GLuint Context::createTexture()
555{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500556 return mState.mTextures->createTexture();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000557}
558
559GLuint Context::createRenderbuffer()
560{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500561 return mState.mRenderbuffers->createRenderbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000562}
563
Geoff Lang882033e2014-09-30 11:26:07 -0400564GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400565{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500566 GLuint handle = mState.mFenceSyncs->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400567
Cooper Partind8e62a32015-01-29 15:21:25 -0800568 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400569}
570
Sami Väisänene45e53b2016-05-25 10:36:04 +0300571GLuint Context::createPaths(GLsizei range)
572{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500573 auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300574 if (resultOrError.isError())
575 {
576 handleError(resultOrError.getError());
577 return 0;
578 }
579 return resultOrError.getResult();
580}
581
Jamie Madill57a89722013-07-02 11:57:03 -0400582GLuint Context::createVertexArray()
583{
Geoff Lang36167ab2015-12-07 10:27:14 -0500584 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
585 mVertexArrayMap[vertexArray] = nullptr;
586 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400587}
588
Jamie Madilldc356042013-07-19 16:36:57 -0400589GLuint Context::createSampler()
590{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500591 return mState.mSamplers->createSampler();
Jamie Madilldc356042013-07-19 16:36:57 -0400592}
593
Geoff Langc8058452014-02-03 12:04:11 -0500594GLuint Context::createTransformFeedback()
595{
Geoff Lang36167ab2015-12-07 10:27:14 -0500596 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
597 mTransformFeedbackMap[transformFeedback] = nullptr;
598 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500599}
600
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000601// Returns an unused framebuffer name
602GLuint Context::createFramebuffer()
603{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500604 return mState.mFramebuffers->createFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000605}
606
Jamie Madill33dc8432013-07-26 11:55:05 -0400607GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000608{
Jamie Madill33dc8432013-07-26 11:55:05 -0400609 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000610
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400611 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000612
613 return handle;
614}
615
616// Returns an unused query name
617GLuint Context::createQuery()
618{
619 GLuint handle = mQueryHandleAllocator.allocate();
620
621 mQueryMap[handle] = NULL;
622
623 return handle;
624}
625
626void Context::deleteBuffer(GLuint buffer)
627{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500628 if (mState.mBuffers->getBuffer(buffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000629 {
630 detachBuffer(buffer);
631 }
Jamie Madill893ab082014-05-16 16:56:10 -0400632
Jamie Madill6c1f6712017-02-14 19:08:04 -0500633 mState.mBuffers->deleteObject(this, buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000634}
635
636void Context::deleteShader(GLuint shader)
637{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500638 mState.mShaderPrograms->deleteShader(this, shader);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000639}
640
641void Context::deleteProgram(GLuint program)
642{
Jamie Madill6c1f6712017-02-14 19:08:04 -0500643 mState.mShaderPrograms->deleteProgram(this, program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000644}
645
646void Context::deleteTexture(GLuint texture)
647{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500648 if (mState.mTextures->getTexture(texture))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000649 {
650 detachTexture(texture);
651 }
652
Jamie Madill6c1f6712017-02-14 19:08:04 -0500653 mState.mTextures->deleteObject(this, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000654}
655
656void Context::deleteRenderbuffer(GLuint renderbuffer)
657{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500658 if (mState.mRenderbuffers->getRenderbuffer(renderbuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659 {
660 detachRenderbuffer(renderbuffer);
661 }
Jamie Madill893ab082014-05-16 16:56:10 -0400662
Jamie Madill6c1f6712017-02-14 19:08:04 -0500663 mState.mRenderbuffers->deleteObject(this, renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664}
665
Jamie Madillcd055f82013-07-26 11:55:15 -0400666void Context::deleteFenceSync(GLsync fenceSync)
667{
668 // The spec specifies the underlying Fence object is not deleted until all current
669 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
670 // and since our API is currently designed for being called from a single thread, we can delete
671 // the fence immediately.
Jamie Madill6c1f6712017-02-14 19:08:04 -0500672 mState.mFenceSyncs->deleteObject(this,
673 static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400674}
675
Sami Väisänene45e53b2016-05-25 10:36:04 +0300676void Context::deletePaths(GLuint first, GLsizei range)
677{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500678 mState.mPaths->deletePaths(first, range);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300679}
680
681bool Context::hasPathData(GLuint path) const
682{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500683 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300684 if (pathObj == nullptr)
685 return false;
686
687 return pathObj->hasPathData();
688}
689
690bool Context::hasPath(GLuint path) const
691{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500692 return mState.mPaths->hasPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300693}
694
695void Context::setPathCommands(GLuint path,
696 GLsizei numCommands,
697 const GLubyte *commands,
698 GLsizei numCoords,
699 GLenum coordType,
700 const void *coords)
701{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500702 auto *pathObject = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300703
704 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
705}
706
707void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
708{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500709 auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300710
711 switch (pname)
712 {
713 case GL_PATH_STROKE_WIDTH_CHROMIUM:
714 pathObj->setStrokeWidth(value);
715 break;
716 case GL_PATH_END_CAPS_CHROMIUM:
717 pathObj->setEndCaps(static_cast<GLenum>(value));
718 break;
719 case GL_PATH_JOIN_STYLE_CHROMIUM:
720 pathObj->setJoinStyle(static_cast<GLenum>(value));
721 break;
722 case GL_PATH_MITER_LIMIT_CHROMIUM:
723 pathObj->setMiterLimit(value);
724 break;
725 case GL_PATH_STROKE_BOUND_CHROMIUM:
726 pathObj->setStrokeBound(value);
727 break;
728 default:
729 UNREACHABLE();
730 break;
731 }
732}
733
734void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
735{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500736 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +0300737
738 switch (pname)
739 {
740 case GL_PATH_STROKE_WIDTH_CHROMIUM:
741 *value = pathObj->getStrokeWidth();
742 break;
743 case GL_PATH_END_CAPS_CHROMIUM:
744 *value = static_cast<GLfloat>(pathObj->getEndCaps());
745 break;
746 case GL_PATH_JOIN_STYLE_CHROMIUM:
747 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
748 break;
749 case GL_PATH_MITER_LIMIT_CHROMIUM:
750 *value = pathObj->getMiterLimit();
751 break;
752 case GL_PATH_STROKE_BOUND_CHROMIUM:
753 *value = pathObj->getStrokeBound();
754 break;
755 default:
756 UNREACHABLE();
757 break;
758 }
759}
760
761void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
762{
763 mGLState.setPathStencilFunc(func, ref, mask);
764}
765
Jamie Madill57a89722013-07-02 11:57:03 -0400766void Context::deleteVertexArray(GLuint vertexArray)
767{
Geoff Lang36167ab2015-12-07 10:27:14 -0500768 auto iter = mVertexArrayMap.find(vertexArray);
769 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000770 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500771 VertexArray *vertexArrayObject = iter->second;
772 if (vertexArrayObject != nullptr)
773 {
774 detachVertexArray(vertexArray);
775 delete vertexArrayObject;
776 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000777
Geoff Lang36167ab2015-12-07 10:27:14 -0500778 mVertexArrayMap.erase(iter);
779 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400780 }
781}
782
Jamie Madilldc356042013-07-19 16:36:57 -0400783void Context::deleteSampler(GLuint sampler)
784{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500785 if (mState.mSamplers->getSampler(sampler))
Jamie Madilldc356042013-07-19 16:36:57 -0400786 {
787 detachSampler(sampler);
788 }
789
Jamie Madill6c1f6712017-02-14 19:08:04 -0500790 mState.mSamplers->deleteObject(this, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400791}
792
Geoff Langc8058452014-02-03 12:04:11 -0500793void Context::deleteTransformFeedback(GLuint transformFeedback)
794{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500795 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500796 if (iter != mTransformFeedbackMap.end())
797 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500798 TransformFeedback *transformFeedbackObject = iter->second;
799 if (transformFeedbackObject != nullptr)
800 {
801 detachTransformFeedback(transformFeedback);
Jamie Madill6c1f6712017-02-14 19:08:04 -0500802 transformFeedbackObject->release(this);
Geoff Lang36167ab2015-12-07 10:27:14 -0500803 }
804
Geoff Lang50b3fe82015-12-08 14:49:12 +0000805 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500806 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500807 }
808}
809
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810void Context::deleteFramebuffer(GLuint framebuffer)
811{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500812 if (mState.mFramebuffers->getFramebuffer(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813 {
814 detachFramebuffer(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -0500816
Jamie Madill6c1f6712017-02-14 19:08:04 -0500817 mState.mFramebuffers->deleteObject(this, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818}
819
Jamie Madill33dc8432013-07-26 11:55:05 -0400820void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500822 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823
Jamie Madill33dc8432013-07-26 11:55:05 -0400824 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000825 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400826 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000827 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400828 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000829 }
830}
831
832void Context::deleteQuery(GLuint query)
833{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500834 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 if (queryObject != mQueryMap.end())
836 {
837 mQueryHandleAllocator.release(queryObject->first);
838 if (queryObject->second)
839 {
840 queryObject->second->release();
841 }
842 mQueryMap.erase(queryObject);
843 }
844}
845
Geoff Lang70d0f492015-12-10 17:45:46 -0500846Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500848 return mState.mBuffers->getBuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849}
850
Jamie Madill570f7c82014-07-03 10:38:54 -0400851Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500853 return mState.mTextures->getTexture(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000854}
855
Geoff Lang70d0f492015-12-10 17:45:46 -0500856Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500858 return mState.mRenderbuffers->getRenderbuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000859}
860
Jamie Madillcd055f82013-07-26 11:55:15 -0400861FenceSync *Context::getFenceSync(GLsync handle) const
862{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500863 return mState.mFenceSyncs->getFenceSync(
864 static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400865}
866
Jamie Madill57a89722013-07-02 11:57:03 -0400867VertexArray *Context::getVertexArray(GLuint handle) const
868{
869 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500870 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400871}
872
Jamie Madilldc356042013-07-19 16:36:57 -0400873Sampler *Context::getSampler(GLuint handle) const
874{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500875 return mState.mSamplers->getSampler(handle);
Jamie Madilldc356042013-07-19 16:36:57 -0400876}
877
Geoff Langc8058452014-02-03 12:04:11 -0500878TransformFeedback *Context::getTransformFeedback(GLuint handle) const
879{
Geoff Lang36167ab2015-12-07 10:27:14 -0500880 auto iter = mTransformFeedbackMap.find(handle);
881 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500882}
883
Geoff Lang70d0f492015-12-10 17:45:46 -0500884LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
885{
886 switch (identifier)
887 {
888 case GL_BUFFER:
889 return getBuffer(name);
890 case GL_SHADER:
891 return getShader(name);
892 case GL_PROGRAM:
893 return getProgram(name);
894 case GL_VERTEX_ARRAY:
895 return getVertexArray(name);
896 case GL_QUERY:
897 return getQuery(name);
898 case GL_TRANSFORM_FEEDBACK:
899 return getTransformFeedback(name);
900 case GL_SAMPLER:
901 return getSampler(name);
902 case GL_TEXTURE:
903 return getTexture(name);
904 case GL_RENDERBUFFER:
905 return getRenderbuffer(name);
906 case GL_FRAMEBUFFER:
907 return getFramebuffer(name);
908 default:
909 UNREACHABLE();
910 return nullptr;
911 }
912}
913
914LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
915{
916 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
917}
918
Martin Radev9d901792016-07-15 15:58:58 +0300919void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
920{
921 LabeledObject *object = getLabeledObject(identifier, name);
922 ASSERT(object != nullptr);
923
924 std::string labelName = GetObjectLabelFromPointer(length, label);
925 object->setLabel(labelName);
926}
927
928void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
929{
930 LabeledObject *object = getLabeledObjectFromPtr(ptr);
931 ASSERT(object != nullptr);
932
933 std::string labelName = GetObjectLabelFromPointer(length, label);
934 object->setLabel(labelName);
935}
936
937void Context::getObjectLabel(GLenum identifier,
938 GLuint name,
939 GLsizei bufSize,
940 GLsizei *length,
941 GLchar *label) const
942{
943 LabeledObject *object = getLabeledObject(identifier, name);
944 ASSERT(object != nullptr);
945
946 const std::string &objectLabel = object->getLabel();
947 GetObjectLabelBase(objectLabel, bufSize, length, label);
948}
949
950void Context::getObjectPtrLabel(const void *ptr,
951 GLsizei bufSize,
952 GLsizei *length,
953 GLchar *label) const
954{
955 LabeledObject *object = getLabeledObjectFromPtr(ptr);
956 ASSERT(object != nullptr);
957
958 const std::string &objectLabel = object->getLabel();
959 GetObjectLabelBase(objectLabel, bufSize, length, label);
960}
961
Jamie Madilldc356042013-07-19 16:36:57 -0400962bool Context::isSampler(GLuint samplerName) const
963{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500964 return mState.mSamplers->isSampler(samplerName);
Jamie Madilldc356042013-07-19 16:36:57 -0400965}
966
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500967void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000968{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500969 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700970 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000971}
972
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800973void Context::bindDrawIndirectBuffer(GLuint bufferHandle)
974{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500975 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800976 mGLState.setDrawIndirectBufferBinding(buffer);
977}
978
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500979void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980{
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500981 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700982 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000983}
984
Jamie Madilldedd7b92014-11-05 16:30:36 -0500985void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000986{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500987 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988
Jamie Madilldedd7b92014-11-05 16:30:36 -0500989 if (handle == 0)
990 {
991 texture = mZeroTextures[target].get();
992 }
993 else
994 {
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500995 texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500996 }
997
998 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700999 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001000}
1001
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001002void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001003{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001004 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1005 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007}
1008
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001009void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001010{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001011 Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation(
1012 mImplementation.get(), mCaps, framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001014}
1015
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001016void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -04001017{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001018 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -04001020}
1021
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001022void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -04001023{
Geoff Lang76b10c92014-09-05 16:28:14 -04001024 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -04001025 Sampler *sampler =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001026 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001027 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001028}
1029
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001030void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001031{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001032 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001033 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001034}
1035
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001036void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
1037 GLuint index,
1038 GLintptr offset,
1039 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001040{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001041 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001042 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001043}
1044
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001045void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001046{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001047 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001048 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001049}
1050
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001051void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
1052 GLuint index,
1053 GLintptr offset,
1054 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001055{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001056 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001057 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001058}
1059
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001060void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001061{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001062 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001063 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001064}
1065
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001066void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001067{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001068 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001069 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001070}
1071
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001072void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001073{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001074 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001075 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001076}
1077
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001078void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001079{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001080 Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001081 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001082}
1083
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084void Context::useProgram(GLuint program)
1085{
Jamie Madill6c1f6712017-02-14 19:08:04 -05001086 mGLState.setProgram(this, getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001087}
1088
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001089void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -05001090{
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001091 TransformFeedback *transformFeedback =
1092 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001093 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001094}
1095
Geoff Lang5aad9672014-09-08 11:10:42 -04001096Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001097{
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001098 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001099 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100
Geoff Lang5aad9672014-09-08 11:10:42 -04001101 // begin query
1102 Error error = queryObject->begin();
1103 if (error.isError())
1104 {
1105 return error;
1106 }
1107
1108 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001109 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001110
He Yunchaoacd18982017-01-04 10:46:42 +08001111 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001112}
1113
Geoff Lang5aad9672014-09-08 11:10:42 -04001114Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001116 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001117 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001118
Geoff Lang5aad9672014-09-08 11:10:42 -04001119 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001120
Geoff Lang5aad9672014-09-08 11:10:42 -04001121 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001122 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001123
1124 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001125}
1126
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001127Error Context::queryCounter(GLuint id, GLenum target)
1128{
1129 ASSERT(target == GL_TIMESTAMP_EXT);
1130
1131 Query *queryObject = getQuery(id, true, target);
1132 ASSERT(queryObject);
1133
1134 return queryObject->queryCounter();
1135}
1136
1137void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1138{
1139 switch (pname)
1140 {
1141 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001142 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001143 break;
1144 case GL_QUERY_COUNTER_BITS_EXT:
1145 switch (target)
1146 {
1147 case GL_TIME_ELAPSED_EXT:
1148 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1149 break;
1150 case GL_TIMESTAMP_EXT:
1151 params[0] = getExtensions().queryCounterBitsTimestamp;
1152 break;
1153 default:
1154 UNREACHABLE();
1155 params[0] = 0;
1156 break;
1157 }
1158 break;
1159 default:
1160 UNREACHABLE();
1161 return;
1162 }
1163}
1164
Geoff Lang2186c382016-10-14 10:54:54 -04001165void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001166{
Geoff Lang2186c382016-10-14 10:54:54 -04001167 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001168}
1169
Geoff Lang2186c382016-10-14 10:54:54 -04001170void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001171{
Geoff Lang2186c382016-10-14 10:54:54 -04001172 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001173}
1174
Geoff Lang2186c382016-10-14 10:54:54 -04001175void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001176{
Geoff Lang2186c382016-10-14 10:54:54 -04001177 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001178}
1179
Geoff Lang2186c382016-10-14 10:54:54 -04001180void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001181{
Geoff Lang2186c382016-10-14 10:54:54 -04001182 handleError(GetQueryObjectParameter(getQuery(id), pname, params));
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001183}
1184
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001185Framebuffer *Context::getFramebuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05001187 return mState.mFramebuffers->getFramebuffer(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001188}
1189
Jamie Madill33dc8432013-07-26 11:55:05 -04001190FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001191{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001192 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193
Jamie Madill33dc8432013-07-26 11:55:05 -04001194 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001195 {
1196 return NULL;
1197 }
1198 else
1199 {
1200 return fence->second;
1201 }
1202}
1203
1204Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1205{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001206 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001207
1208 if (query == mQueryMap.end())
1209 {
1210 return NULL;
1211 }
1212 else
1213 {
1214 if (!query->second && create)
1215 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001216 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001217 query->second->addRef();
1218 }
1219 return query->second;
1220 }
1221}
1222
Geoff Lang70d0f492015-12-10 17:45:46 -05001223Query *Context::getQuery(GLuint handle) const
1224{
1225 auto iter = mQueryMap.find(handle);
1226 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1227}
1228
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001229Texture *Context::getTargetTexture(GLenum target) const
1230{
Ian Ewellbda75592016-04-18 17:25:54 -04001231 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001232 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001233}
1234
Geoff Lang76b10c92014-09-05 16:28:14 -04001235Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001237 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238}
1239
Geoff Lang492a7e42014-11-05 13:27:06 -05001240Compiler *Context::getCompiler() const
1241{
1242 return mCompiler;
1243}
1244
Jamie Madill893ab082014-05-16 16:56:10 -04001245void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246{
1247 switch (pname)
1248 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001249 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001250 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001252 mGLState.getBooleanv(pname, params);
1253 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001254 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255}
1256
Jamie Madill893ab082014-05-16 16:56:10 -04001257void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258{
Shannon Woods53a94a82014-06-24 15:20:36 -04001259 // Queries about context capabilities and maximums are answered by Context.
1260 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 switch (pname)
1262 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001263 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001264 params[0] = mCaps.minAliasedLineWidth;
1265 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001266 break;
1267 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001268 params[0] = mCaps.minAliasedPointSize;
1269 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001271 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001272 ASSERT(mExtensions.textureFilterAnisotropic);
1273 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001274 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001275 case GL_MAX_TEXTURE_LOD_BIAS:
1276 *params = mCaps.maxLODBias;
1277 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001278
1279 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1280 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1281 {
1282 ASSERT(mExtensions.pathRendering);
1283 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1284 memcpy(params, m, 16 * sizeof(GLfloat));
1285 }
1286 break;
1287
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001289 mGLState.getFloatv(pname, params);
1290 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001291 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001292}
1293
Jamie Madill893ab082014-05-16 16:56:10 -04001294void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001295{
Shannon Woods53a94a82014-06-24 15:20:36 -04001296 // Queries about context capabilities and maximums are answered by Context.
1297 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001298
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001299 switch (pname)
1300 {
Geoff Lang301d1612014-07-09 10:34:37 -04001301 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1302 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1303 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1305 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1306 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001307 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1308 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1309 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001310 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001311 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1312 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1313 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001314 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001315 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001316 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1317 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1318 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1319 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001320 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1321 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001322 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1323 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001324 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001325 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1326 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1327 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1328 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Martin Radev1be913c2016-07-11 17:59:16 +03001329 case GL_MAJOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001330 *params = getClientVersion().major;
Martin Radev1be913c2016-07-11 17:59:16 +03001331 break;
1332 case GL_MINOR_VERSION:
Geoff Langeb66a6e2016-10-31 13:06:12 -04001333 *params = getClientVersion().minor;
Martin Radev1be913c2016-07-11 17:59:16 +03001334 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001335 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1336 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001337 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1338 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1339 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001340 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1341 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1342 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001343 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001344 case GL_MAX_VIEWPORT_DIMS:
1345 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001346 params[0] = mCaps.maxViewportWidth;
1347 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001348 }
1349 break;
1350 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001351 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1354 *params = mResetStrategy;
1355 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001356 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001357 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001358 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001359 case GL_SHADER_BINARY_FORMATS:
1360 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1361 break;
1362 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001363 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001364 break;
1365 case GL_PROGRAM_BINARY_FORMATS:
1366 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001367 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001368 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001369 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001370 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001371
1372 // GL_KHR_debug
1373 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1374 *params = mExtensions.maxDebugMessageLength;
1375 break;
1376 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1377 *params = mExtensions.maxDebugLoggedMessages;
1378 break;
1379 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1380 *params = mExtensions.maxDebugGroupStackDepth;
1381 break;
1382 case GL_MAX_LABEL_LENGTH:
1383 *params = mExtensions.maxLabelLength;
1384 break;
1385
Ian Ewell53f59f42016-01-28 17:36:55 -05001386 // GL_EXT_disjoint_timer_query
1387 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001388 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001389 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001390 case GL_MAX_FRAMEBUFFER_WIDTH:
1391 *params = mCaps.maxFramebufferWidth;
1392 break;
1393 case GL_MAX_FRAMEBUFFER_HEIGHT:
1394 *params = mCaps.maxFramebufferHeight;
1395 break;
1396 case GL_MAX_FRAMEBUFFER_SAMPLES:
1397 *params = mCaps.maxFramebufferSamples;
1398 break;
1399 case GL_MAX_SAMPLE_MASK_WORDS:
1400 *params = mCaps.maxSampleMaskWords;
1401 break;
1402 case GL_MAX_COLOR_TEXTURE_SAMPLES:
1403 *params = mCaps.maxColorTextureSamples;
1404 break;
1405 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
1406 *params = mCaps.maxDepthTextureSamples;
1407 break;
1408 case GL_MAX_INTEGER_SAMPLES:
1409 *params = mCaps.maxIntegerSamples;
1410 break;
1411 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
1412 *params = mCaps.maxVertexAttribRelativeOffset;
1413 break;
1414 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
1415 *params = mCaps.maxVertexAttribBindings;
1416 break;
1417 case GL_MAX_VERTEX_ATTRIB_STRIDE:
1418 *params = mCaps.maxVertexAttribStride;
1419 break;
1420 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
1421 *params = mCaps.maxVertexAtomicCounterBuffers;
1422 break;
1423 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
1424 *params = mCaps.maxVertexAtomicCounters;
1425 break;
1426 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
1427 *params = mCaps.maxVertexImageUniforms;
1428 break;
1429 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
1430 *params = mCaps.maxVertexShaderStorageBlocks;
1431 break;
1432 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
1433 *params = mCaps.maxFragmentAtomicCounterBuffers;
1434 break;
1435 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
1436 *params = mCaps.maxFragmentAtomicCounters;
1437 break;
1438 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
1439 *params = mCaps.maxFragmentImageUniforms;
1440 break;
1441 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
1442 *params = mCaps.maxFragmentShaderStorageBlocks;
1443 break;
1444 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
1445 *params = mCaps.minProgramTextureGatherOffset;
1446 break;
1447 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
1448 *params = mCaps.maxProgramTextureGatherOffset;
1449 break;
1450 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
1451 *params = mCaps.maxComputeWorkGroupInvocations;
1452 break;
1453 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
1454 *params = mCaps.maxComputeUniformBlocks;
1455 break;
1456 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
1457 *params = mCaps.maxComputeTextureImageUnits;
1458 break;
1459 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
1460 *params = mCaps.maxComputeSharedMemorySize;
1461 break;
1462 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
1463 *params = mCaps.maxComputeUniformComponents;
1464 break;
1465 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
1466 *params = mCaps.maxComputeAtomicCounterBuffers;
1467 break;
1468 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
1469 *params = mCaps.maxComputeAtomicCounters;
1470 break;
1471 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
1472 *params = mCaps.maxComputeImageUniforms;
1473 break;
1474 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
1475 *params = mCaps.maxCombinedComputeUniformComponents;
1476 break;
1477 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
1478 *params = mCaps.maxComputeShaderStorageBlocks;
1479 break;
1480 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
1481 *params = mCaps.maxCombinedShaderOutputResources;
1482 break;
1483 case GL_MAX_UNIFORM_LOCATIONS:
1484 *params = mCaps.maxUniformLocations;
1485 break;
1486 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
1487 *params = mCaps.maxAtomicCounterBufferBindings;
1488 break;
1489 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
1490 *params = mCaps.maxAtomicCounterBufferSize;
1491 break;
1492 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
1493 *params = mCaps.maxCombinedAtomicCounterBuffers;
1494 break;
1495 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
1496 *params = mCaps.maxCombinedAtomicCounters;
1497 break;
1498 case GL_MAX_IMAGE_UNITS:
1499 *params = mCaps.maxImageUnits;
1500 break;
1501 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
1502 *params = mCaps.maxCombinedImageUniforms;
1503 break;
1504 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
1505 *params = mCaps.maxShaderStorageBufferBindings;
1506 break;
1507 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
1508 *params = mCaps.maxCombinedShaderStorageBlocks;
1509 break;
1510 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
1511 *params = mCaps.shaderStorageBufferOffsetAlignment;
1512 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001513 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001514 mGLState.getIntegerv(mState, pname, params);
1515 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001516 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001517}
1518
Jamie Madill893ab082014-05-16 16:56:10 -04001519void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001520{
Shannon Woods53a94a82014-06-24 15:20:36 -04001521 // Queries about context capabilities and maximums are answered by Context.
1522 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001523 switch (pname)
1524 {
1525 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001526 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001527 break;
1528 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001529 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001530 break;
1531 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001532 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001533 break;
1534 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001535 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001536 break;
1537 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001538 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001539 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001540
1541 // GL_EXT_disjoint_timer_query
1542 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001543 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001544 break;
Martin Radev66fb8202016-07-28 11:45:20 +03001545
1546 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
1547 *params = mCaps.maxShaderStorageBlockSize;
1548 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001549 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001550 UNREACHABLE();
1551 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001552 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001553}
1554
Geoff Lang70d0f492015-12-10 17:45:46 -05001555void Context::getPointerv(GLenum pname, void **params) const
1556{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001557 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001558}
1559
Martin Radev66fb8202016-07-28 11:45:20 +03001560void Context::getIntegeri_v(GLenum target, GLuint index, GLint *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);
1568 ASSERT(queryStatus);
1569
1570 if (nativeType == GL_INT)
1571 {
1572 switch (target)
1573 {
1574 case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
1575 ASSERT(index < 3u);
1576 *data = mCaps.maxComputeWorkGroupCount[index];
1577 break;
1578 case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
1579 ASSERT(index < 3u);
1580 *data = mCaps.maxComputeWorkGroupSize[index];
1581 break;
1582 default:
1583 mGLState.getIntegeri_v(target, index, data);
1584 }
1585 }
1586 else
1587 {
1588 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1589 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001590}
1591
Martin Radev66fb8202016-07-28 11:45:20 +03001592void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods1b2fb852013-08-19 14:28:48 -04001593{
Shannon Woods53a94a82014-06-24 15:20:36 -04001594 // Queries about context capabilities and maximums are answered by Context.
1595 // Queries about current GL state values are answered by State.
Martin Radev66fb8202016-07-28 11:45:20 +03001596
1597 GLenum nativeType;
1598 unsigned int numParams;
1599 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1600 ASSERT(queryStatus);
1601
1602 if (nativeType == GL_INT_64_ANGLEX)
1603 {
1604 mGLState.getInteger64i_v(target, index, data);
1605 }
1606 else
1607 {
1608 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1609 }
1610}
1611
1612void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1613{
1614 // Queries about context capabilities and maximums are answered by Context.
1615 // Queries about current GL state values are answered by State.
1616
1617 GLenum nativeType;
1618 unsigned int numParams;
1619 bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
1620 ASSERT(queryStatus);
1621
1622 if (nativeType == GL_BOOL)
1623 {
1624 mGLState.getBooleani_v(target, index, data);
1625 }
1626 else
1627 {
1628 CastIndexedStateValues(this, nativeType, target, index, numParams, data);
1629 }
Shannon Woods1b2fb852013-08-19 14:28:48 -04001630}
1631
Jamie Madill675fe712016-12-19 13:07:54 -05001632void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001633{
Jamie Madill1b94d432015-08-07 13:23:23 -04001634 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001635 auto error = mImplementation->drawArrays(mode, first, count);
1636 handleError(error);
1637 if (!error.isError())
1638 {
1639 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1640 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001641}
1642
Jamie Madill675fe712016-12-19 13:07:54 -05001643void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Geoff Langf6db0982015-08-25 13:04:00 -04001644{
1645 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001646 auto error = mImplementation->drawArraysInstanced(mode, first, count, instanceCount);
1647 handleError(error);
1648 if (!error.isError())
1649 {
1650 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
1651 }
Geoff Langf6db0982015-08-25 13:04:00 -04001652}
1653
Jamie Madill675fe712016-12-19 13:07:54 -05001654void Context::drawElements(GLenum mode,
1655 GLsizei count,
1656 GLenum type,
1657 const GLvoid *indices,
1658 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Jamie Madill1b94d432015-08-07 13:23:23 -04001660 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001661 handleError(mImplementation->drawElements(mode, count, type, indices, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001662}
1663
Jamie Madill675fe712016-12-19 13:07:54 -05001664void Context::drawElementsInstanced(GLenum mode,
1665 GLsizei count,
1666 GLenum type,
1667 const GLvoid *indices,
1668 GLsizei instances,
1669 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001670{
1671 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001672 handleError(
1673 mImplementation->drawElementsInstanced(mode, count, type, indices, instances, indexRange));
Geoff Langf6db0982015-08-25 13:04:00 -04001674}
1675
Jamie Madill675fe712016-12-19 13:07:54 -05001676void Context::drawRangeElements(GLenum mode,
1677 GLuint start,
1678 GLuint end,
1679 GLsizei count,
1680 GLenum type,
1681 const GLvoid *indices,
1682 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001683{
1684 syncRendererState();
Jamie Madill675fe712016-12-19 13:07:54 -05001685 handleError(
1686 mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687}
1688
Jiajia Qind9671222016-11-29 16:30:31 +08001689void Context::drawArraysIndirect(GLenum mode, const GLvoid *indirect)
1690{
1691 syncRendererState();
1692 handleError(mImplementation->drawArraysIndirect(mode, indirect));
1693}
1694
1695void Context::drawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
1696{
1697 syncRendererState();
1698 handleError(mImplementation->drawElementsIndirect(mode, type, indirect));
1699}
1700
Jamie Madill675fe712016-12-19 13:07:54 -05001701void Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001702{
Jamie Madill675fe712016-12-19 13:07:54 -05001703 handleError(mImplementation->flush());
Geoff Lang129753a2015-01-09 16:52:09 -05001704}
1705
Jamie Madill675fe712016-12-19 13:07:54 -05001706void Context::finish()
Geoff Lang129753a2015-01-09 16:52:09 -05001707{
Jamie Madill675fe712016-12-19 13:07:54 -05001708 handleError(mImplementation->finish());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001709}
1710
Austin Kinross6ee1e782015-05-29 17:05:37 -07001711void Context::insertEventMarker(GLsizei length, const char *marker)
1712{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001713 ASSERT(mImplementation);
1714 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001715}
1716
1717void Context::pushGroupMarker(GLsizei length, const char *marker)
1718{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001719 ASSERT(mImplementation);
1720 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001721}
1722
1723void Context::popGroupMarker()
1724{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001725 ASSERT(mImplementation);
1726 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001727}
1728
Geoff Langd8605522016-04-13 10:19:12 -04001729void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1730{
1731 Program *programObject = getProgram(program);
1732 ASSERT(programObject);
1733
1734 programObject->bindUniformLocation(location, name);
1735}
1736
Sami Väisänena797e062016-05-12 15:23:40 +03001737void Context::setCoverageModulation(GLenum components)
1738{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001739 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001740}
1741
Sami Väisänene45e53b2016-05-25 10:36:04 +03001742void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1743{
1744 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1745}
1746
1747void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1748{
1749 GLfloat I[16];
1750 angle::Matrix<GLfloat>::setToIdentity(I);
1751
1752 mGLState.loadPathRenderingMatrix(matrixMode, I);
1753}
1754
1755void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1756{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001757 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001758 if (!pathObj)
1759 return;
1760
1761 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1762 syncRendererState();
1763
1764 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1765}
1766
1767void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1768{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001769 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001770 if (!pathObj)
1771 return;
1772
1773 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1774 syncRendererState();
1775
1776 mImplementation->stencilStrokePath(pathObj, reference, mask);
1777}
1778
1779void Context::coverFillPath(GLuint path, GLenum coverMode)
1780{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001781 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001782 if (!pathObj)
1783 return;
1784
1785 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1786 syncRendererState();
1787
1788 mImplementation->coverFillPath(pathObj, coverMode);
1789}
1790
1791void Context::coverStrokePath(GLuint path, GLenum coverMode)
1792{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001793 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001794 if (!pathObj)
1795 return;
1796
1797 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1798 syncRendererState();
1799
1800 mImplementation->coverStrokePath(pathObj, coverMode);
1801}
1802
1803void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1804{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001805 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001806 if (!pathObj)
1807 return;
1808
1809 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1810 syncRendererState();
1811
1812 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1813}
1814
1815void Context::stencilThenCoverStrokePath(GLuint path,
1816 GLint reference,
1817 GLuint mask,
1818 GLenum coverMode)
1819{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001820 const auto *pathObj = mState.mPaths->getPath(path);
Sami Väisänene45e53b2016-05-25 10:36:04 +03001821 if (!pathObj)
1822 return;
1823
1824 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1825 syncRendererState();
1826
1827 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1828}
1829
Sami Väisänend59ca052016-06-21 16:10:00 +03001830void Context::coverFillPathInstanced(GLsizei numPaths,
1831 GLenum pathNameType,
1832 const void *paths,
1833 GLuint pathBase,
1834 GLenum coverMode,
1835 GLenum transformType,
1836 const GLfloat *transformValues)
1837{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001838 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001839
1840 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1841 syncRendererState();
1842
1843 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1844}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001845
Sami Väisänend59ca052016-06-21 16:10:00 +03001846void Context::coverStrokePathInstanced(GLsizei numPaths,
1847 GLenum pathNameType,
1848 const void *paths,
1849 GLuint pathBase,
1850 GLenum coverMode,
1851 GLenum transformType,
1852 const GLfloat *transformValues)
1853{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001854 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001855
1856 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1857 syncRendererState();
1858
1859 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1860 transformValues);
1861}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001862
Sami Väisänend59ca052016-06-21 16:10:00 +03001863void Context::stencilFillPathInstanced(GLsizei numPaths,
1864 GLenum pathNameType,
1865 const void *paths,
1866 GLuint pathBase,
1867 GLenum fillMode,
1868 GLuint mask,
1869 GLenum transformType,
1870 const GLfloat *transformValues)
1871{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001872 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001873
1874 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1875 syncRendererState();
1876
1877 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1878 transformValues);
1879}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001880
Sami Väisänend59ca052016-06-21 16:10:00 +03001881void Context::stencilStrokePathInstanced(GLsizei numPaths,
1882 GLenum pathNameType,
1883 const void *paths,
1884 GLuint pathBase,
1885 GLint reference,
1886 GLuint mask,
1887 GLenum transformType,
1888 const GLfloat *transformValues)
1889{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001890 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001891
1892 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1893 syncRendererState();
1894
1895 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1896 transformValues);
1897}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001898
Sami Väisänend59ca052016-06-21 16:10:00 +03001899void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1900 GLenum pathNameType,
1901 const void *paths,
1902 GLuint pathBase,
1903 GLenum fillMode,
1904 GLuint mask,
1905 GLenum coverMode,
1906 GLenum transformType,
1907 const GLfloat *transformValues)
1908{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001909 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001910
1911 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1912 syncRendererState();
1913
1914 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1915 transformType, transformValues);
1916}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001917
Sami Väisänend59ca052016-06-21 16:10:00 +03001918void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1919 GLenum pathNameType,
1920 const void *paths,
1921 GLuint pathBase,
1922 GLint reference,
1923 GLuint mask,
1924 GLenum coverMode,
1925 GLenum transformType,
1926 const GLfloat *transformValues)
1927{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05001928 const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase);
Sami Väisänend59ca052016-06-21 16:10:00 +03001929
1930 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1931 syncRendererState();
1932
1933 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1934 transformType, transformValues);
1935}
1936
Sami Väisänen46eaa942016-06-29 10:26:37 +03001937void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1938{
1939 auto *programObject = getProgram(program);
1940
1941 programObject->bindFragmentInputLocation(location, name);
1942}
1943
1944void Context::programPathFragmentInputGen(GLuint program,
1945 GLint location,
1946 GLenum genMode,
1947 GLint components,
1948 const GLfloat *coeffs)
1949{
1950 auto *programObject = getProgram(program);
1951
1952 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1953}
1954
Jamie Madill437fa652016-05-03 15:13:24 -04001955void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001956{
Geoff Langda5777c2014-07-11 09:52:58 -04001957 if (error.isError())
1958 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001959 GLenum code = error.getCode();
1960 mErrors.insert(code);
1961 if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
1962 {
1963 markContextLost();
1964 }
Geoff Lang70d0f492015-12-10 17:45:46 -05001965
1966 if (!error.getMessage().empty())
1967 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001968 auto *debug = &mGLState.getDebug();
1969 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1970 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001971 }
Geoff Langda5777c2014-07-11 09:52:58 -04001972 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001973}
1974
1975// Get one of the recorded errors and clear its flag, if any.
1976// [OpenGL ES 2.0.24] section 2.5 page 13.
1977GLenum Context::getError()
1978{
Geoff Langda5777c2014-07-11 09:52:58 -04001979 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001980 {
Geoff Langda5777c2014-07-11 09:52:58 -04001981 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001982 }
Geoff Langda5777c2014-07-11 09:52:58 -04001983 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001984 {
Geoff Langda5777c2014-07-11 09:52:58 -04001985 GLenum error = *mErrors.begin();
1986 mErrors.erase(mErrors.begin());
1987 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001988 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001989}
1990
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001991// NOTE: this function should not assume that this context is current!
1992void Context::markContextLost()
1993{
1994 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001995 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001996 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
Kenneth Russellf2f6f652016-10-05 19:53:23 -07001997 mContextLostForced = true;
1998 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04001999 mContextLost = true;
2000}
2001
2002bool Context::isContextLost()
2003{
2004 return mContextLost;
2005}
2006
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007GLenum Context::getResetStatus()
2008{
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002009 // Even if the application doesn't want to know about resets, we want to know
2010 // as it will allow us to skip all the calls.
2011 if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002012 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002013 if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR)
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002014 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002015 mContextLost = true;
Jamie Madill9dd0cf02014-11-24 11:38:51 -05002016 }
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002017
2018 // EXT_robustness, section 2.6: If the reset notification behavior is
2019 // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
2020 // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
2021 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002022 }
2023
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002024 // The GL_EXT_robustness spec says that if a reset is encountered, a reset
2025 // status should be returned at least once, and GL_NO_ERROR should be returned
2026 // once the device has finished resetting.
2027 if (!mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002028 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002029 ASSERT(mResetStatus == GL_NO_ERROR);
2030 mResetStatus = mImplementation->getResetStatus();
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00002031
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002032 if (mResetStatus != GL_NO_ERROR)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002033 {
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002034 mContextLost = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002035 }
2036 }
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002037 else if (!mContextLostForced && mResetStatus != GL_NO_ERROR)
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002038 {
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002039 // If markContextLost was used to mark the context lost then
2040 // assume that is not recoverable, and continue to report the
2041 // lost reset status for the lifetime of this context.
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002042 mResetStatus = mImplementation->getResetStatus();
2043 }
Jamie Madill893ab082014-05-16 16:56:10 -04002044
Corentin Wallez87fbe1c2016-08-03 14:41:42 -04002045 return mResetStatus;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002046}
2047
2048bool Context::isResetNotificationEnabled()
2049{
2050 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2051}
2052
Corentin Walleze3b10e82015-05-20 11:06:25 -04002053const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01002054{
Corentin Walleze3b10e82015-05-20 11:06:25 -04002055 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01002056}
2057
2058EGLenum Context::getClientType() const
2059{
2060 return mClientType;
2061}
2062
2063EGLenum Context::getRenderBuffer() const
2064{
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002065 const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0);
2066 if (framebuffer == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -04002067 {
2068 return EGL_NONE;
2069 }
Geoff Lang3bf8e3a2016-12-01 17:28:52 -05002070
2071 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
2072 ASSERT(backAttachment != nullptr);
2073 return backAttachment->getSurface()->getRenderBuffer();
Régis Fénéon83107972015-02-05 12:57:44 +01002074}
2075
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002076VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002077{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002078 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002079 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
2080 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05002081 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002082 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
2083
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002084 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002085 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002086
2087 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05002088}
2089
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002090TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05002091{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05002092 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002093 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
2094 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05002095 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002096 transformFeedback =
2097 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002098 transformFeedback->addRef();
2099 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002100 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05002101
2102 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05002103}
2104
2105bool Context::isVertexArrayGenerated(GLuint vertexArray)
2106{
Geoff Langf41a7152016-09-19 15:11:17 -04002107 ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002108 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
2109}
2110
2111bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
2112{
Geoff Langf41a7152016-09-19 15:11:17 -04002113 ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end());
Geoff Lang36167ab2015-12-07 10:27:14 -05002114 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
2115}
2116
Shannon Woods53a94a82014-06-24 15:20:36 -04002117void Context::detachTexture(GLuint texture)
2118{
2119 // Simple pass-through to State's detachTexture method, as textures do not require
2120 // allocation map management either here or in the resource manager at detach time.
2121 // Zero textures are held by the Context, and we don't attempt to request them from
2122 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002123 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04002124}
2125
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002126void Context::detachBuffer(GLuint buffer)
2127{
Yuly Novikov5807a532015-12-03 13:01:22 -05002128 // Simple pass-through to State's detachBuffer method, since
2129 // only buffer attachments to container objects that are bound to the current context
2130 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04002131
Yuly Novikov5807a532015-12-03 13:01:22 -05002132 // [OpenGL ES 3.2] section 5.1.2 page 45:
2133 // Attachments to unbound container objects, such as
2134 // deletion of a buffer attached to a vertex array object which is not bound to the context,
2135 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002136 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002137}
2138
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002139void Context::detachFramebuffer(GLuint framebuffer)
2140{
Shannon Woods53a94a82014-06-24 15:20:36 -04002141 // Framebuffer detachment is handled by Context, because 0 is a valid
2142 // Framebuffer object, and a pointer to it must be passed from Context
2143 // to State at binding time.
2144
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145 // [OpenGL ES 2.0.24] section 4.4 page 107:
2146 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2147 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2148
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002149 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002150 {
2151 bindReadFramebuffer(0);
2152 }
2153
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002154 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002155 {
2156 bindDrawFramebuffer(0);
2157 }
2158}
2159
2160void Context::detachRenderbuffer(GLuint renderbuffer)
2161{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002162 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163}
2164
Jamie Madill57a89722013-07-02 11:57:03 -04002165void Context::detachVertexArray(GLuint vertexArray)
2166{
Jamie Madill77a72f62015-04-14 11:18:32 -04002167 // Vertex array detachment is handled by Context, because 0 is a valid
2168 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04002169 // binding time.
2170
Jamie Madill57a89722013-07-02 11:57:03 -04002171 // [OpenGL ES 3.0.2] section 2.10 page 43:
2172 // If a vertex array object that is currently bound is deleted, the binding
2173 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002174 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002175 {
2176 bindVertexArray(0);
2177 }
2178}
2179
Geoff Langc8058452014-02-03 12:04:11 -05002180void Context::detachTransformFeedback(GLuint transformFeedback)
2181{
Corentin Walleza2257da2016-04-19 16:43:12 -04002182 // Transform feedback detachment is handled by Context, because 0 is a valid
2183 // transform feedback, and a pointer to it must be passed from Context to State at
2184 // binding time.
2185
2186 // The OpenGL specification doesn't mention what should happen when the currently bound
2187 // transform feedback object is deleted. Since it is a container object, we treat it like
2188 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002189 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04002190 {
2191 bindTransformFeedback(0);
2192 }
Geoff Langc8058452014-02-03 12:04:11 -05002193}
2194
Jamie Madilldc356042013-07-19 16:36:57 -04002195void Context::detachSampler(GLuint sampler)
2196{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002197 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002198}
2199
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002200void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2201{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002202 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002203}
2204
Jamie Madille29d1672013-07-19 16:36:57 -04002205void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2206{
Geoff Langc1984ed2016-10-07 12:41:00 -04002207 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002208 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002209 SetSamplerParameteri(samplerObject, pname, param);
2210}
Jamie Madille29d1672013-07-19 16:36:57 -04002211
Geoff Langc1984ed2016-10-07 12:41:00 -04002212void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
2213{
2214 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002215 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002216 SetSamplerParameteriv(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002217}
2218
2219void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2220{
Geoff Langc1984ed2016-10-07 12:41:00 -04002221 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002222 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002223 SetSamplerParameterf(samplerObject, pname, param);
Jamie Madille29d1672013-07-19 16:36:57 -04002224}
2225
Geoff Langc1984ed2016-10-07 12:41:00 -04002226void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
Jamie Madill9675b802013-07-19 16:36:59 -04002227{
Geoff Langc1984ed2016-10-07 12:41:00 -04002228 Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002229 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002230 SetSamplerParameterfv(samplerObject, pname, param);
Jamie Madill9675b802013-07-19 16:36:59 -04002231}
2232
Geoff Langc1984ed2016-10-07 12:41:00 -04002233void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
Jamie Madill9675b802013-07-19 16:36:59 -04002234{
Geoff Langc1984ed2016-10-07 12:41:00 -04002235 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002236 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002237 QuerySamplerParameteriv(samplerObject, pname, params);
2238}
Jamie Madill9675b802013-07-19 16:36:59 -04002239
Geoff Langc1984ed2016-10-07 12:41:00 -04002240void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
2241{
2242 const Sampler *samplerObject =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05002243 mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler);
Geoff Langc1984ed2016-10-07 12:41:00 -04002244 QuerySamplerParameterfv(samplerObject, pname, params);
Jamie Madill9675b802013-07-19 16:36:59 -04002245}
2246
Olli Etuahof0fee072016-03-30 15:11:58 +03002247void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2248{
2249 gl::Program *programObject = getProgram(program);
2250 ASSERT(programObject != nullptr);
2251
2252 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2253 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2254}
2255
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002256void Context::initRendererString()
2257{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002258 std::ostringstream rendererString;
2259 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002260 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002261 rendererString << ")";
2262
Geoff Langcec35902014-04-16 10:52:36 -04002263 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002264}
2265
Geoff Langc339c4e2016-11-29 10:37:36 -05002266void Context::initVersionStrings()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002267{
Geoff Langc339c4e2016-11-29 10:37:36 -05002268 const Version &clientVersion = getClientVersion();
2269
2270 std::ostringstream versionString;
2271 versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE "
2272 << ANGLE_VERSION_STRING << ")";
2273 mVersionString = MakeStaticString(versionString.str());
2274
2275 std::ostringstream shadingLanguageVersionString;
2276 shadingLanguageVersionString << "OpenGL ES GLSL ES "
2277 << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
2278 << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING
2279 << ")";
2280 mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002281}
2282
Geoff Langcec35902014-04-16 10:52:36 -04002283void Context::initExtensionStrings()
2284{
Geoff Langc339c4e2016-11-29 10:37:36 -05002285 auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
2286 std::ostringstream combinedStringStream;
2287 std::copy(strings.begin(), strings.end(),
2288 std::ostream_iterator<const char *>(combinedStringStream, " "));
2289 return MakeStaticString(combinedStringStream.str());
2290 };
2291
2292 mExtensionStrings.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002293 for (const auto &extensionString : mExtensions.getStrings())
2294 {
2295 mExtensionStrings.push_back(MakeStaticString(extensionString));
2296 }
Geoff Langc339c4e2016-11-29 10:37:36 -05002297 mExtensionString = mergeExtensionStrings(mExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002298
Bryan Bernhart58806562017-01-05 13:09:31 -08002299 const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions();
2300
Geoff Langc339c4e2016-11-29 10:37:36 -05002301 mRequestableExtensionStrings.clear();
2302 for (const auto &extensionInfo : GetExtensionInfoMap())
2303 {
2304 if (extensionInfo.second.Requestable &&
Bryan Bernhart58806562017-01-05 13:09:31 -08002305 !(mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
2306 nativeExtensions.*(extensionInfo.second.ExtensionsMember))
Geoff Langc339c4e2016-11-29 10:37:36 -05002307 {
2308 mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
2309 }
2310 }
2311 mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
Geoff Langcec35902014-04-16 10:52:36 -04002312}
2313
Geoff Langc339c4e2016-11-29 10:37:36 -05002314const GLubyte *Context::getString(GLenum name) const
Geoff Langcec35902014-04-16 10:52:36 -04002315{
Geoff Langc339c4e2016-11-29 10:37:36 -05002316 switch (name)
2317 {
2318 case GL_VENDOR:
2319 return reinterpret_cast<const GLubyte *>("Google Inc.");
2320
2321 case GL_RENDERER:
2322 return reinterpret_cast<const GLubyte *>(mRendererString);
2323
2324 case GL_VERSION:
2325 return reinterpret_cast<const GLubyte *>(mVersionString);
2326
2327 case GL_SHADING_LANGUAGE_VERSION:
2328 return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
2329
2330 case GL_EXTENSIONS:
2331 return reinterpret_cast<const GLubyte *>(mExtensionString);
2332
2333 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2334 return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
2335
2336 default:
2337 UNREACHABLE();
2338 return nullptr;
2339 }
Geoff Langcec35902014-04-16 10:52:36 -04002340}
2341
Geoff Langc339c4e2016-11-29 10:37:36 -05002342const GLubyte *Context::getStringi(GLenum name, GLuint index) const
Geoff Langcec35902014-04-16 10:52:36 -04002343{
Geoff Langc339c4e2016-11-29 10:37:36 -05002344 switch (name)
2345 {
2346 case GL_EXTENSIONS:
2347 return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
2348
2349 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
2350 return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
2351
2352 default:
2353 UNREACHABLE();
2354 return nullptr;
2355 }
Geoff Langcec35902014-04-16 10:52:36 -04002356}
2357
2358size_t Context::getExtensionStringCount() const
2359{
2360 return mExtensionStrings.size();
2361}
2362
Geoff Langc339c4e2016-11-29 10:37:36 -05002363void Context::requestExtension(const char *name)
2364{
2365 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
2366 ASSERT(extensionInfos.find(name) != extensionInfos.end());
2367 const auto &extension = extensionInfos.at(name);
2368 ASSERT(extension.Requestable);
2369
2370 if (mExtensions.*(extension.ExtensionsMember))
2371 {
2372 // Extension already enabled
2373 return;
2374 }
2375
2376 mExtensions.*(extension.ExtensionsMember) = true;
2377 updateCaps();
2378 initExtensionStrings();
Bryan Bernhart58806562017-01-05 13:09:31 -08002379
2380 // Re-create the compiler with the requested extensions enabled.
2381 SafeDelete(mCompiler);
2382 mCompiler = new Compiler(mImplementation.get(), mState);
Geoff Langc339c4e2016-11-29 10:37:36 -05002383}
2384
2385size_t Context::getRequestableExtensionStringCount() const
2386{
2387 return mRequestableExtensionStrings.size();
2388}
2389
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002390void Context::beginTransformFeedback(GLenum primitiveMode)
2391{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002392 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002393 ASSERT(transformFeedback != nullptr);
2394 ASSERT(!transformFeedback->isPaused());
2395
Jamie Madill6c1f6712017-02-14 19:08:04 -05002396 transformFeedback->begin(this, primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002397}
2398
2399bool Context::hasActiveTransformFeedback(GLuint program) const
2400{
2401 for (auto pair : mTransformFeedbackMap)
2402 {
2403 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2404 {
2405 return true;
2406 }
2407 }
2408 return false;
2409}
2410
Corentin Wallezc295e512017-01-27 17:47:50 -05002411void Context::initCaps(bool webGLContext, const egl::DisplayExtensions &displayExtensions)
Geoff Lang493daf52014-07-03 13:38:44 -04002412{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002413 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002414
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002415 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002416
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002417 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002418
Geoff Langeb66a6e2016-10-31 13:06:12 -04002419 if (getClientVersion() < Version(3, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002420 {
2421 // Disable ES3+ extensions
2422 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002423 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002424 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002425 }
2426
Geoff Langeb66a6e2016-10-31 13:06:12 -04002427 if (getClientVersion() > Version(2, 0))
Geoff Lang493daf52014-07-03 13:38:44 -04002428 {
2429 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2430 //mExtensions.sRGB = false;
2431 }
2432
Jamie Madill00ed7a12016-05-19 13:13:38 -04002433 // Some extensions are always available because they are implemented in the GL layer.
2434 mExtensions.bindUniformLocation = true;
2435 mExtensions.vertexArrayObject = true;
Geoff Langf41a7152016-09-19 15:11:17 -04002436 mExtensions.bindGeneratesResource = true;
Geoff Langfeb8c682017-02-13 16:07:35 -05002437 mExtensions.clientArrays = true;
Geoff Langc339c4e2016-11-29 10:37:36 -05002438 mExtensions.requestExtension = true;
Jamie Madill00ed7a12016-05-19 13:13:38 -04002439
2440 // Enable the no error extension if the context was created with the flag.
2441 mExtensions.noError = mSkipValidation;
2442
Corentin Wallezccab69d2017-01-27 16:57:15 -05002443 // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
Corentin Wallezc295e512017-01-27 17:47:50 -05002444 mExtensions.surfacelessContext = displayExtensions.surfacelessContext;
Corentin Wallezccab69d2017-01-27 16:57:15 -05002445
Geoff Lang70d0f492015-12-10 17:45:46 -05002446 // Explicitly enable GL_KHR_debug
2447 mExtensions.debug = true;
2448 mExtensions.maxDebugMessageLength = 1024;
2449 mExtensions.maxDebugLoggedMessages = 1024;
2450 mExtensions.maxDebugGroupStackDepth = 1024;
2451 mExtensions.maxLabelLength = 1024;
2452
Geoff Langff5b2d52016-09-07 11:32:23 -04002453 // Explicitly enable GL_ANGLE_robust_client_memory
2454 mExtensions.robustClientMemory = true;
2455
Geoff Lang301d1612014-07-09 10:34:37 -04002456 // Apply implementation limits
2457 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002458 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2459 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2460
2461 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002462
Geoff Langc287ea62016-09-16 14:46:51 -04002463 // WebGL compatibility
2464 mExtensions.webglCompatibility = webGLContext;
2465 for (const auto &extensionInfo : GetExtensionInfoMap())
2466 {
2467 // If this context is for WebGL, disable all enableable extensions
Geoff Langc339c4e2016-11-29 10:37:36 -05002468 if (webGLContext && extensionInfo.second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04002469 {
2470 mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
2471 }
2472 }
2473
2474 // Generate texture caps
2475 updateCaps();
2476}
2477
2478void Context::updateCaps()
2479{
Geoff Lang900013c2014-07-07 11:32:19 -04002480 mCaps.compressedTextureFormats.clear();
Geoff Langc287ea62016-09-16 14:46:51 -04002481 mTextureCaps.clear();
Geoff Lang900013c2014-07-07 11:32:19 -04002482
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002483 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002484 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2485 {
2486 GLenum format = i->first;
2487 TextureCaps formatCaps = i->second;
2488
Geoff Lang5d601382014-07-22 15:14:06 -04002489 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002490
Geoff Lang0d8b7242015-09-09 14:56:53 -04002491 // Update the format caps based on the client version and extensions.
2492 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2493 // ES3.
2494 formatCaps.texturable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002495 formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002496 formatCaps.renderable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002497 formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002498 formatCaps.filterable =
Geoff Langeb66a6e2016-10-31 13:06:12 -04002499 formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002500
He Yunchaoccd8c9b2017-01-18 17:36:14 +08002501 // OpenGL ES does not support multisampling with non-rendererable formats
2502 // OpenGL ES 3.0 or prior does not support multisampling with integer formats
2503 if (!formatInfo.renderSupport ||
2504 (getClientVersion() < ES_3_1 &&
2505 (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)))
Geoff Lang493daf52014-07-03 13:38:44 -04002506 {
Geoff Langd87878e2014-09-19 15:42:59 -04002507 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002508 }
Geoff Langd87878e2014-09-19 15:42:59 -04002509
2510 if (formatCaps.texturable && formatInfo.compressed)
2511 {
2512 mCaps.compressedTextureFormats.push_back(format);
2513 }
2514
2515 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002516 }
2517}
2518
Kenneth Russellf2f6f652016-10-05 19:53:23 -07002519void Context::initWorkarounds()
2520{
2521 // Lose the context upon out of memory error if the application is
2522 // expecting to watch for those events.
2523 mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2524}
2525
Jamie Madill1b94d432015-08-07 13:23:23 -04002526void Context::syncRendererState()
2527{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002528 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2529 mImplementation->syncState(mGLState, dirtyBits);
2530 mGLState.clearDirtyBits();
2531 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002532}
2533
Jamie Madillad9f24e2016-02-12 09:27:24 -05002534void Context::syncRendererState(const State::DirtyBits &bitMask,
2535 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002536{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002537 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2538 mImplementation->syncState(mGLState, dirtyBits);
2539 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002540
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002541 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002542}
Jamie Madillc29968b2016-01-20 11:17:23 -05002543
2544void Context::blitFramebuffer(GLint srcX0,
2545 GLint srcY0,
2546 GLint srcX1,
2547 GLint srcY1,
2548 GLint dstX0,
2549 GLint dstY0,
2550 GLint dstX1,
2551 GLint dstY1,
2552 GLbitfield mask,
2553 GLenum filter)
2554{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002555 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 ASSERT(drawFramebuffer);
2557
2558 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2559 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2560
Jamie Madillad9f24e2016-02-12 09:27:24 -05002561 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002562
Jamie Madill8415b5f2016-04-26 13:41:39 -04002563 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002564}
Jamie Madillc29968b2016-01-20 11:17:23 -05002565
2566void Context::clear(GLbitfield mask)
2567{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002568 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002569 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002570}
2571
2572void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2573{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002574 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002575 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2576 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002577}
2578
2579void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2580{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002581 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002582 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2583 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002584}
2585
2586void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2587{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002588 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002589 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2590 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002591}
2592
2593void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2594{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002595 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002596 ASSERT(framebufferObject);
2597
2598 // If a buffer is not present, the clear has no effect
2599 if (framebufferObject->getDepthbuffer() == nullptr &&
2600 framebufferObject->getStencilbuffer() == nullptr)
2601 {
2602 return;
2603 }
2604
Jamie Madillad9f24e2016-02-12 09:27:24 -05002605 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002606 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2607 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002608}
2609
2610void Context::readPixels(GLint x,
2611 GLint y,
2612 GLsizei width,
2613 GLsizei height,
2614 GLenum format,
2615 GLenum type,
2616 GLvoid *pixels)
2617{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002618 if (width == 0 || height == 0)
2619 {
2620 return;
2621 }
2622
Jamie Madillad9f24e2016-02-12 09:27:24 -05002623 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002624
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002625 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002626 ASSERT(framebufferObject);
2627
2628 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002629 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002630}
2631
2632void Context::copyTexImage2D(GLenum target,
2633 GLint level,
2634 GLenum internalformat,
2635 GLint x,
2636 GLint y,
2637 GLsizei width,
2638 GLsizei height,
2639 GLint border)
2640{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002641 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002642 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002643
Jamie Madillc29968b2016-01-20 11:17:23 -05002644 Rectangle sourceArea(x, y, width, height);
2645
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002646 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002647 Texture *texture =
2648 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002649 handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002650}
2651
2652void Context::copyTexSubImage2D(GLenum target,
2653 GLint level,
2654 GLint xoffset,
2655 GLint yoffset,
2656 GLint x,
2657 GLint y,
2658 GLsizei width,
2659 GLsizei height)
2660{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002661 if (width == 0 || height == 0)
2662 {
2663 return;
2664 }
2665
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002666 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002667 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002668
Jamie Madillc29968b2016-01-20 11:17:23 -05002669 Offset destOffset(xoffset, yoffset, 0);
2670 Rectangle sourceArea(x, y, width, height);
2671
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002672 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002673 Texture *texture =
2674 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002675 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002676}
2677
2678void Context::copyTexSubImage3D(GLenum target,
2679 GLint level,
2680 GLint xoffset,
2681 GLint yoffset,
2682 GLint zoffset,
2683 GLint x,
2684 GLint y,
2685 GLsizei width,
2686 GLsizei height)
2687{
Corentin Wallez9a8d3662016-09-22 12:18:29 -04002688 if (width == 0 || height == 0)
2689 {
2690 return;
2691 }
2692
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002693 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002694 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002695
Jamie Madillc29968b2016-01-20 11:17:23 -05002696 Offset destOffset(xoffset, yoffset, zoffset);
2697 Rectangle sourceArea(x, y, width, height);
2698
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002699 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002700 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002701 handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002702}
2703
2704void Context::framebufferTexture2D(GLenum target,
2705 GLenum attachment,
2706 GLenum textarget,
2707 GLuint texture,
2708 GLint level)
2709{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002710 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002711 ASSERT(framebuffer);
2712
2713 if (texture != 0)
2714 {
2715 Texture *textureObj = getTexture(texture);
2716
2717 ImageIndex index = ImageIndex::MakeInvalid();
2718
2719 if (textarget == GL_TEXTURE_2D)
2720 {
2721 index = ImageIndex::Make2D(level);
2722 }
JiangYizhoubddc46b2016-12-09 09:50:51 +08002723 else if (textarget == GL_TEXTURE_2D_MULTISAMPLE)
2724 {
2725 ASSERT(level == 0);
2726 index = ImageIndex::Make2DMultisample();
2727 }
Jamie Madillc29968b2016-01-20 11:17:23 -05002728 else
2729 {
2730 ASSERT(IsCubeMapTextureTarget(textarget));
2731 index = ImageIndex::MakeCube(textarget, level);
2732 }
2733
2734 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2735 }
2736 else
2737 {
2738 framebuffer->resetAttachment(attachment);
2739 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002740
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002742}
2743
2744void Context::framebufferRenderbuffer(GLenum target,
2745 GLenum attachment,
2746 GLenum renderbuffertarget,
2747 GLuint renderbuffer)
2748{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002749 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002750 ASSERT(framebuffer);
2751
2752 if (renderbuffer != 0)
2753 {
2754 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2755 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2756 renderbufferObject);
2757 }
2758 else
2759 {
2760 framebuffer->resetAttachment(attachment);
2761 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002762
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002763 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002764}
2765
2766void Context::framebufferTextureLayer(GLenum target,
2767 GLenum attachment,
2768 GLuint texture,
2769 GLint level,
2770 GLint layer)
2771{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002772 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002773 ASSERT(framebuffer);
2774
2775 if (texture != 0)
2776 {
2777 Texture *textureObject = getTexture(texture);
2778
2779 ImageIndex index = ImageIndex::MakeInvalid();
2780
2781 if (textureObject->getTarget() == GL_TEXTURE_3D)
2782 {
2783 index = ImageIndex::Make3D(level, layer);
2784 }
2785 else
2786 {
2787 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2788 index = ImageIndex::Make2DArray(level, layer);
2789 }
2790
2791 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2792 }
2793 else
2794 {
2795 framebuffer->resetAttachment(attachment);
2796 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002797
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002798 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002799}
2800
2801void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2802{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002803 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002804 ASSERT(framebuffer);
2805 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002806 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002807}
2808
2809void Context::readBuffer(GLenum mode)
2810{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002812 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002813 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002814}
2815
2816void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2817{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002818 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002820
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002821 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002822 ASSERT(framebuffer);
2823
2824 // The specification isn't clear what should be done when the framebuffer isn't complete.
2825 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002826 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002827}
2828
2829void Context::invalidateFramebuffer(GLenum target,
2830 GLsizei numAttachments,
2831 const GLenum *attachments)
2832{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002833 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002834 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002835
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002836 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002837 ASSERT(framebuffer);
2838
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002839 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002840 {
Jamie Madill437fa652016-05-03 15:13:24 -04002841 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002842 }
Jamie Madill437fa652016-05-03 15:13:24 -04002843
2844 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002845}
2846
2847void Context::invalidateSubFramebuffer(GLenum target,
2848 GLsizei numAttachments,
2849 const GLenum *attachments,
2850 GLint x,
2851 GLint y,
2852 GLsizei width,
2853 GLsizei height)
2854{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002855 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002856 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002857
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002859 ASSERT(framebuffer);
2860
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002861 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002862 {
Jamie Madill437fa652016-05-03 15:13:24 -04002863 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002864 }
Jamie Madill437fa652016-05-03 15:13:24 -04002865
2866 Rectangle area(x, y, width, height);
2867 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002868}
2869
Jamie Madill73a84962016-02-12 09:27:23 -05002870void Context::texImage2D(GLenum target,
2871 GLint level,
2872 GLint internalformat,
2873 GLsizei width,
2874 GLsizei height,
2875 GLint border,
2876 GLenum format,
2877 GLenum type,
2878 const GLvoid *pixels)
2879{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002880 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002881
2882 Extents size(width, height, 1);
2883 Texture *texture =
2884 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002885 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2886 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002887}
2888
2889void Context::texImage3D(GLenum target,
2890 GLint level,
2891 GLint internalformat,
2892 GLsizei width,
2893 GLsizei height,
2894 GLsizei depth,
2895 GLint border,
2896 GLenum format,
2897 GLenum type,
2898 const GLvoid *pixels)
2899{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002900 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002901
2902 Extents size(width, height, depth);
2903 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002904 handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat,
2905 size, format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002906}
2907
2908void Context::texSubImage2D(GLenum target,
2909 GLint level,
2910 GLint xoffset,
2911 GLint yoffset,
2912 GLsizei width,
2913 GLsizei height,
2914 GLenum format,
2915 GLenum type,
2916 const GLvoid *pixels)
2917{
2918 // Zero sized uploads are valid but no-ops
2919 if (width == 0 || height == 0)
2920 {
2921 return;
2922 }
2923
Jamie Madillad9f24e2016-02-12 09:27:24 -05002924 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002925
2926 Box area(xoffset, yoffset, 0, width, height, 1);
2927 Texture *texture =
2928 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002929 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2930 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002931}
2932
2933void Context::texSubImage3D(GLenum target,
2934 GLint level,
2935 GLint xoffset,
2936 GLint yoffset,
2937 GLint zoffset,
2938 GLsizei width,
2939 GLsizei height,
2940 GLsizei depth,
2941 GLenum format,
2942 GLenum type,
2943 const GLvoid *pixels)
2944{
2945 // Zero sized uploads are valid but no-ops
2946 if (width == 0 || height == 0 || depth == 0)
2947 {
2948 return;
2949 }
2950
Jamie Madillad9f24e2016-02-12 09:27:24 -05002951 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002952
2953 Box area(xoffset, yoffset, zoffset, width, height, depth);
2954 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002955 handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
2956 type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002957}
2958
2959void Context::compressedTexImage2D(GLenum target,
2960 GLint level,
2961 GLenum internalformat,
2962 GLsizei width,
2963 GLsizei height,
2964 GLint border,
2965 GLsizei imageSize,
2966 const GLvoid *data)
2967{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002968 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002969
2970 Extents size(width, height, 1);
2971 Texture *texture =
2972 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002973 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002974 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002975 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002976}
2977
2978void Context::compressedTexImage3D(GLenum target,
2979 GLint level,
2980 GLenum internalformat,
2981 GLsizei width,
2982 GLsizei height,
2983 GLsizei depth,
2984 GLint border,
2985 GLsizei imageSize,
2986 const GLvoid *data)
2987{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002988 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002989
2990 Extents size(width, height, depth);
2991 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05002992 handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002993 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002994 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002995}
2996
2997void Context::compressedTexSubImage2D(GLenum target,
2998 GLint level,
2999 GLint xoffset,
3000 GLint yoffset,
3001 GLsizei width,
3002 GLsizei height,
3003 GLenum format,
3004 GLsizei imageSize,
3005 const GLvoid *data)
3006{
Jamie Madillad9f24e2016-02-12 09:27:24 -05003007 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003008
3009 Box area(xoffset, yoffset, 0, width, height, 1);
3010 Texture *texture =
3011 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003012 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003013 format, imageSize,
3014 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003015}
3016
3017void Context::compressedTexSubImage3D(GLenum target,
3018 GLint level,
3019 GLint xoffset,
3020 GLint yoffset,
3021 GLint zoffset,
3022 GLsizei width,
3023 GLsizei height,
3024 GLsizei depth,
3025 GLenum format,
3026 GLsizei imageSize,
3027 const GLvoid *data)
3028{
3029 // Zero sized uploads are valid but no-ops
3030 if (width == 0 || height == 0)
3031 {
3032 return;
3033 }
3034
Jamie Madillad9f24e2016-02-12 09:27:24 -05003035 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05003036
3037 Box area(xoffset, yoffset, zoffset, width, height, depth);
3038 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003039 handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area,
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003040 format, imageSize,
3041 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05003042}
3043
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003044void Context::generateMipmap(GLenum target)
3045{
3046 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003047 handleError(texture->generateMipmap(this));
Olli Etuaho0f2b1562016-05-13 16:15:35 +03003048}
3049
Geoff Lang97073d12016-04-20 10:42:34 -07003050void Context::copyTextureCHROMIUM(GLuint sourceId,
3051 GLuint destId,
3052 GLint internalFormat,
3053 GLenum destType,
3054 GLboolean unpackFlipY,
3055 GLboolean unpackPremultiplyAlpha,
3056 GLboolean unpackUnmultiplyAlpha)
3057{
3058 syncStateForTexImage();
3059
3060 gl::Texture *sourceTexture = getTexture(sourceId);
3061 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003062 handleError(destTexture->copyTexture(this, internalFormat, destType, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003063 unpackPremultiplyAlpha == GL_TRUE,
3064 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3065}
3066
3067void Context::copySubTextureCHROMIUM(GLuint sourceId,
3068 GLuint destId,
3069 GLint xoffset,
3070 GLint yoffset,
3071 GLint x,
3072 GLint y,
3073 GLsizei width,
3074 GLsizei height,
3075 GLboolean unpackFlipY,
3076 GLboolean unpackPremultiplyAlpha,
3077 GLboolean unpackUnmultiplyAlpha)
3078{
3079 // Zero sized copies are valid but no-ops
3080 if (width == 0 || height == 0)
3081 {
3082 return;
3083 }
3084
3085 syncStateForTexImage();
3086
3087 gl::Texture *sourceTexture = getTexture(sourceId);
3088 gl::Texture *destTexture = getTexture(destId);
3089 Offset offset(xoffset, yoffset, 0);
3090 Rectangle area(x, y, width, height);
Jamie Madill8897afa2017-02-06 17:17:23 -05003091 handleError(destTexture->copySubTexture(this, offset, area, unpackFlipY == GL_TRUE,
Geoff Lang97073d12016-04-20 10:42:34 -07003092 unpackPremultiplyAlpha == GL_TRUE,
3093 unpackUnmultiplyAlpha == GL_TRUE, sourceTexture));
3094}
3095
Geoff Lang47110bf2016-04-20 11:13:22 -07003096void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
3097{
3098 syncStateForTexImage();
3099
3100 gl::Texture *sourceTexture = getTexture(sourceId);
3101 gl::Texture *destTexture = getTexture(destId);
Jamie Madill8897afa2017-02-06 17:17:23 -05003102 handleError(destTexture->copyCompressedTexture(this, sourceTexture));
Geoff Lang47110bf2016-04-20 11:13:22 -07003103}
3104
Geoff Lang496c02d2016-10-20 11:38:11 -07003105void Context::getBufferPointerv(GLenum target, GLenum pname, void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003106{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003107 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003108 ASSERT(buffer);
3109
Geoff Lang496c02d2016-10-20 11:38:11 -07003110 QueryBufferPointerv(buffer, pname, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003111}
3112
3113GLvoid *Context::mapBuffer(GLenum target, GLenum access)
3114{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003115 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003116 ASSERT(buffer);
3117
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003118 Error error = buffer->map(this, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003119 if (error.isError())
3120 {
Jamie Madill437fa652016-05-03 15:13:24 -04003121 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003122 return nullptr;
3123 }
3124
3125 return buffer->getMapPointer();
3126}
3127
3128GLboolean Context::unmapBuffer(GLenum target)
3129{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003130 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003131 ASSERT(buffer);
3132
3133 GLboolean result;
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003134 Error error = buffer->unmap(this, &result);
Olli Etuaho4f667482016-03-30 15:56:35 +03003135 if (error.isError())
3136 {
Jamie Madill437fa652016-05-03 15:13:24 -04003137 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003138 return GL_FALSE;
3139 }
3140
3141 return result;
3142}
3143
3144GLvoid *Context::mapBufferRange(GLenum target,
3145 GLintptr offset,
3146 GLsizeiptr length,
3147 GLbitfield access)
3148{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003149 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003150 ASSERT(buffer);
3151
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003152 Error error = buffer->mapRange(this, offset, length, access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003153 if (error.isError())
3154 {
Jamie Madill437fa652016-05-03 15:13:24 -04003155 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03003156 return nullptr;
3157 }
3158
3159 return buffer->getMapPointer();
3160}
3161
3162void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
3163{
3164 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
3165}
3166
Jamie Madillad9f24e2016-02-12 09:27:24 -05003167void Context::syncStateForReadPixels()
3168{
3169 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
3170}
3171
3172void Context::syncStateForTexImage()
3173{
3174 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
3175}
3176
3177void Context::syncStateForClear()
3178{
3179 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
3180}
3181
3182void Context::syncStateForBlit()
3183{
3184 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
3185}
3186
Jamie Madillc20ab272016-06-09 07:20:46 -07003187void Context::activeTexture(GLenum texture)
3188{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003189 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003190}
3191
3192void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3193{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003194 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07003195}
3196
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003197void Context::blendEquation(GLenum mode)
3198{
3199 mGLState.setBlendEquation(mode, mode);
3200}
3201
Jamie Madillc20ab272016-06-09 07:20:46 -07003202void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
3203{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003204 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003205}
3206
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05003207void Context::blendFunc(GLenum sfactor, GLenum dfactor)
3208{
3209 mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
3210}
3211
Jamie Madillc20ab272016-06-09 07:20:46 -07003212void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
3213{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003214 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003215}
3216
3217void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
3218{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003219 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07003220}
3221
3222void Context::clearDepthf(GLclampf depth)
3223{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003224 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07003225}
3226
3227void Context::clearStencil(GLint s)
3228{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003229 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07003230}
3231
3232void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
3233{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003234 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003235}
3236
3237void Context::cullFace(GLenum mode)
3238{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003239 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003240}
3241
3242void Context::depthFunc(GLenum func)
3243{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003244 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07003245}
3246
3247void Context::depthMask(GLboolean flag)
3248{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003249 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003250}
3251
3252void Context::depthRangef(GLclampf zNear, GLclampf zFar)
3253{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003254 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07003255}
3256
3257void Context::disable(GLenum cap)
3258{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003259 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003260}
3261
3262void Context::disableVertexAttribArray(GLuint index)
3263{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003264 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07003265}
3266
3267void Context::enable(GLenum cap)
3268{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003269 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003270}
3271
3272void Context::enableVertexAttribArray(GLuint index)
3273{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003274 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07003275}
3276
3277void Context::frontFace(GLenum mode)
3278{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003279 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003280}
3281
3282void Context::hint(GLenum target, GLenum mode)
3283{
3284 switch (target)
3285 {
3286 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003287 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003288 break;
3289
3290 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003291 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07003292 break;
3293
3294 default:
3295 UNREACHABLE();
3296 return;
3297 }
3298}
3299
3300void Context::lineWidth(GLfloat width)
3301{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003302 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07003303}
3304
3305void Context::pixelStorei(GLenum pname, GLint param)
3306{
3307 switch (pname)
3308 {
3309 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003310 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003311 break;
3312
3313 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003314 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003315 break;
3316
3317 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003318 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07003319 break;
3320
3321 case GL_UNPACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003322 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003323 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003324 break;
3325
3326 case GL_UNPACK_IMAGE_HEIGHT:
Martin Radev1be913c2016-07-11 17:59:16 +03003327 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003328 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003329 break;
3330
3331 case GL_UNPACK_SKIP_IMAGES:
Martin Radev1be913c2016-07-11 17:59:16 +03003332 ASSERT(getClientMajorVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003333 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003334 break;
3335
3336 case GL_UNPACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003337 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003338 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003339 break;
3340
3341 case GL_UNPACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003342 ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003343 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003344 break;
3345
3346 case GL_PACK_ROW_LENGTH:
Martin Radev1be913c2016-07-11 17:59:16 +03003347 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003348 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003349 break;
3350
3351 case GL_PACK_SKIP_ROWS:
Martin Radev1be913c2016-07-11 17:59:16 +03003352 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003353 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003354 break;
3355
3356 case GL_PACK_SKIP_PIXELS:
Martin Radev1be913c2016-07-11 17:59:16 +03003357 ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003358 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07003359 break;
3360
3361 default:
3362 UNREACHABLE();
3363 return;
3364 }
3365}
3366
3367void Context::polygonOffset(GLfloat factor, GLfloat units)
3368{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003369 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07003370}
3371
3372void Context::sampleCoverage(GLclampf value, GLboolean invert)
3373{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003374 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07003375}
3376
3377void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3378{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003379 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003380}
3381
3382void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3383{
3384 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3385 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003386 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003387 }
3388
3389 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3390 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003391 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003392 }
3393}
3394
3395void Context::stencilMaskSeparate(GLenum face, GLuint mask)
3396{
3397 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3398 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003399 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003400 }
3401
3402 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3403 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003404 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07003405 }
3406}
3407
3408void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3409{
3410 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3411 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003412 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003413 }
3414
3415 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3416 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003417 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07003418 }
3419}
3420
3421void Context::vertexAttrib1f(GLuint index, GLfloat x)
3422{
3423 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003424 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003425}
3426
3427void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
3428{
3429 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003430 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003431}
3432
3433void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
3434{
3435 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003436 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003437}
3438
3439void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
3440{
3441 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003442 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003443}
3444
3445void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
3446{
3447 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003448 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003449}
3450
3451void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
3452{
3453 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003454 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003455}
3456
3457void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3458{
3459 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003460 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003461}
3462
3463void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3464{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003465 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003466}
3467
3468void Context::vertexAttribPointer(GLuint index,
3469 GLint size,
3470 GLenum type,
3471 GLboolean normalized,
3472 GLsizei stride,
3473 const GLvoid *ptr)
3474{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003475 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3476 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003477}
3478
3479void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3480{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003481 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003482}
3483
3484void Context::vertexAttribIPointer(GLuint index,
3485 GLint size,
3486 GLenum type,
3487 GLsizei stride,
3488 const GLvoid *pointer)
3489{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003490 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3491 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003492}
3493
3494void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3495{
3496 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003497 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003498}
3499
3500void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3501{
3502 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003503 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003504}
3505
3506void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3507{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003508 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003509}
3510
3511void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3512{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003513 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003514}
3515
3516void Context::debugMessageControl(GLenum source,
3517 GLenum type,
3518 GLenum severity,
3519 GLsizei count,
3520 const GLuint *ids,
3521 GLboolean enabled)
3522{
3523 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003524 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3525 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003526}
3527
3528void Context::debugMessageInsert(GLenum source,
3529 GLenum type,
3530 GLuint id,
3531 GLenum severity,
3532 GLsizei length,
3533 const GLchar *buf)
3534{
3535 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003536 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003537}
3538
3539void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3540{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003541 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003542}
3543
3544GLuint Context::getDebugMessageLog(GLuint count,
3545 GLsizei bufSize,
3546 GLenum *sources,
3547 GLenum *types,
3548 GLuint *ids,
3549 GLenum *severities,
3550 GLsizei *lengths,
3551 GLchar *messageLog)
3552{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003553 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3554 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003555}
3556
3557void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3558{
3559 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003560 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003561}
3562
3563void Context::popDebugGroup()
3564{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003565 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003566}
3567
Jamie Madill29639852016-09-02 15:00:09 -04003568void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
3569{
3570 Buffer *buffer = mGLState.getTargetBuffer(target);
3571 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003572 handleError(buffer->bufferData(this, target, data, size, usage));
Jamie Madill29639852016-09-02 15:00:09 -04003573}
3574
3575void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
3576{
3577 if (data == nullptr)
3578 {
3579 return;
3580 }
3581
3582 Buffer *buffer = mGLState.getTargetBuffer(target);
3583 ASSERT(buffer);
Jamie Madillb8353b02017-01-25 12:57:21 -08003584 handleError(buffer->bufferSubData(this, target, data, size, offset));
Jamie Madill29639852016-09-02 15:00:09 -04003585}
3586
Jamie Madillef300b12016-10-07 15:12:09 -04003587void Context::attachShader(GLuint program, GLuint shader)
3588{
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003589 auto programObject = mState.mShaderPrograms->getProgram(program);
3590 auto shaderObject = mState.mShaderPrograms->getShader(shader);
Jamie Madillef300b12016-10-07 15:12:09 -04003591 ASSERT(programObject && shaderObject);
3592 programObject->attachShader(shaderObject);
3593}
3594
Kenneth Russellf2f6f652016-10-05 19:53:23 -07003595const Workarounds &Context::getWorkarounds() const
3596{
3597 return mWorkarounds;
3598}
3599
Jamie Madillb0817d12016-11-01 15:48:31 -04003600void Context::copyBufferSubData(GLenum readTarget,
3601 GLenum writeTarget,
3602 GLintptr readOffset,
3603 GLintptr writeOffset,
3604 GLsizeiptr size)
3605{
3606 // if size is zero, the copy is a successful no-op
3607 if (size == 0)
3608 {
3609 return;
3610 }
3611
3612 // TODO(jmadill): cache these.
3613 Buffer *readBuffer = mGLState.getTargetBuffer(readTarget);
3614 Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget);
3615
Jamie Madill5f56ddb2017-01-13 17:29:55 -05003616 handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
Jamie Madillb0817d12016-11-01 15:48:31 -04003617}
3618
Jamie Madill01a80ee2016-11-07 12:06:18 -05003619void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
3620{
3621 Program *programObject = getProgram(program);
3622 // TODO(jmadill): Re-use this from the validation if possible.
3623 ASSERT(programObject);
3624 programObject->bindAttributeLocation(index, name);
3625}
3626
3627void Context::bindBuffer(GLenum target, GLuint buffer)
3628{
3629 switch (target)
3630 {
3631 case GL_ARRAY_BUFFER:
3632 bindArrayBuffer(buffer);
3633 break;
3634 case GL_ELEMENT_ARRAY_BUFFER:
3635 bindElementArrayBuffer(buffer);
3636 break;
3637 case GL_COPY_READ_BUFFER:
3638 bindCopyReadBuffer(buffer);
3639 break;
3640 case GL_COPY_WRITE_BUFFER:
3641 bindCopyWriteBuffer(buffer);
3642 break;
3643 case GL_PIXEL_PACK_BUFFER:
3644 bindPixelPackBuffer(buffer);
3645 break;
3646 case GL_PIXEL_UNPACK_BUFFER:
3647 bindPixelUnpackBuffer(buffer);
3648 break;
3649 case GL_UNIFORM_BUFFER:
3650 bindGenericUniformBuffer(buffer);
3651 break;
3652 case GL_TRANSFORM_FEEDBACK_BUFFER:
3653 bindGenericTransformFeedbackBuffer(buffer);
3654 break;
Geoff Lang3b573612016-10-31 14:08:10 -04003655 case GL_ATOMIC_COUNTER_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003656 if (buffer != 0)
3657 {
3658 // Binding buffers to this binding point is not implemented yet.
3659 UNIMPLEMENTED();
3660 }
Geoff Lang3b573612016-10-31 14:08:10 -04003661 break;
3662 case GL_SHADER_STORAGE_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003663 if (buffer != 0)
3664 {
3665 // Binding buffers to this binding point is not implemented yet.
3666 UNIMPLEMENTED();
3667 }
Geoff Lang3b573612016-10-31 14:08:10 -04003668 break;
3669 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08003670 bindDrawIndirectBuffer(buffer);
Geoff Lang3b573612016-10-31 14:08:10 -04003671 break;
3672 case GL_DISPATCH_INDIRECT_BUFFER:
Geoff Lang9f090372016-12-02 10:20:43 -05003673 if (buffer != 0)
3674 {
3675 // Binding buffers to this binding point is not implemented yet.
3676 UNIMPLEMENTED();
3677 }
Geoff Lang3b573612016-10-31 14:08:10 -04003678 break;
Jamie Madill01a80ee2016-11-07 12:06:18 -05003679
3680 default:
3681 UNREACHABLE();
3682 break;
3683 }
3684}
3685
3686void Context::bindFramebuffer(GLenum target, GLuint framebuffer)
3687{
3688 if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3689 {
3690 bindReadFramebuffer(framebuffer);
3691 }
3692
3693 if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
3694 {
3695 bindDrawFramebuffer(framebuffer);
3696 }
3697}
3698
3699void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer)
3700{
3701 ASSERT(target == GL_RENDERBUFFER);
3702 Renderbuffer *object =
Geoff Lang4ddf5af2016-12-01 14:30:44 -05003703 mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer);
Jamie Madill01a80ee2016-11-07 12:06:18 -05003704 mGLState.setRenderbufferBinding(object);
3705}
3706
JiangYizhoubddc46b2016-12-09 09:50:51 +08003707void Context::texStorage2DMultisample(GLenum target,
3708 GLsizei samples,
3709 GLenum internalformat,
3710 GLsizei width,
3711 GLsizei height,
3712 GLboolean fixedsamplelocations)
3713{
3714 Extents size(width, height, 1);
3715 Texture *texture = getTargetTexture(target);
Jamie Madill8897afa2017-02-06 17:17:23 -05003716 handleError(texture->setStorageMultisample(this, target, samples, internalformat, size,
JiangYizhoubddc46b2016-12-09 09:50:51 +08003717 fixedsamplelocations));
3718}
3719
3720void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
3721{
3722 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
3723 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
3724
3725 switch (pname)
3726 {
3727 case GL_SAMPLE_POSITION:
3728 handleError(framebuffer->getSamplePosition(index, val));
3729 break;
3730 default:
3731 UNREACHABLE();
3732 }
3733}
3734
Jamie Madille8fb6402017-02-14 17:56:40 -05003735void Context::renderbufferStorage(GLenum target,
3736 GLenum internalformat,
3737 GLsizei width,
3738 GLsizei height)
3739{
3740 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3741 handleError(renderbuffer->setStorage(internalformat, width, height));
3742}
3743
3744void Context::renderbufferStorageMultisample(GLenum target,
3745 GLsizei samples,
3746 GLenum internalformat,
3747 GLsizei width,
3748 GLsizei height)
3749{
3750
3751 Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer();
3752 handleError(renderbuffer->setStorageMultisample(samples, internalformat, width, height));
3753}
3754
Jamie Madillc29968b2016-01-20 11:17:23 -05003755} // namespace gl