blob: 6ed59e1169eb9d20b91317444d8933f152f000a1 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
Sami Väisänene45e53b2016-05-25 10:36:04 +030014#include <string.h>
Sami Väisänend59ca052016-06-21 16:10:00 +030015#include <vector>
Jamie Madillb9293972015-02-19 11:07:54 -050016
Sami Väisänene45e53b2016-05-25 10:36:04 +030017#include "common/matrix_utils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050019#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050021#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050022#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Fence.h"
24#include "libANGLE/Framebuffer.h"
25#include "libANGLE/FramebufferAttachment.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030026#include "libANGLE/Path.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050028#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050029#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050030#include "libANGLE/ResourceManager.h"
31#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050032#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050033#include "libANGLE/Texture.h"
34#include "libANGLE/TransformFeedback.h"
35#include "libANGLE/VertexArray.h"
36#include "libANGLE/formatutils.h"
37#include "libANGLE/validationES.h"
Jamie Madill437fa652016-05-03 15:13:24 -040038#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040039#include "libANGLE/renderer/EGLImplFactory.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000040
Geoff Langf6db0982015-08-25 13:04:00 -040041namespace
42{
43
Ian Ewell3ffd78b2016-01-22 16:09:42 -050044template <typename T>
Sami Väisänend59ca052016-06-21 16:10:00 +030045std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
46 GLsizei numPaths,
47 const void *paths,
48 GLuint pathBase)
49{
50 std::vector<gl::Path *> ret;
51 ret.reserve(numPaths);
52
53 const auto *nameArray = static_cast<const T *>(paths);
54
55 for (GLsizei i = 0; i < numPaths; ++i)
56 {
57 const GLuint pathName = nameArray[i] + pathBase;
58
59 ret.push_back(resourceManager.getPath(pathName));
60 }
61
62 return ret;
63}
64
65std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager,
66 GLsizei numPaths,
67 GLenum pathNameType,
68 const void *paths,
69 GLuint pathBase)
70{
71 switch (pathNameType)
72 {
73 case GL_UNSIGNED_BYTE:
74 return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase);
75
76 case GL_BYTE:
77 return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase);
78
79 case GL_UNSIGNED_SHORT:
80 return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase);
81
82 case GL_SHORT:
83 return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase);
84
85 case GL_UNSIGNED_INT:
86 return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase);
87
88 case GL_INT:
89 return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase);
90 }
91
92 UNREACHABLE();
93 return std::vector<gl::Path *>();
94}
95
96template <typename T>
Ian Ewell3ffd78b2016-01-22 16:09:42 -050097gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
98{
99 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
100 ASSERT(queryObject != nullptr);
101
102 switch (pname)
103 {
104 case GL_QUERY_RESULT_EXT:
105 return queryObject->getResult(params);
106 case GL_QUERY_RESULT_AVAILABLE_EXT:
107 {
108 bool available;
109 gl::Error error = queryObject->isResultAvailable(&available);
110 if (!error.isError())
111 {
112 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
113 }
114 return error;
115 }
116 default:
117 UNREACHABLE();
118 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
119 }
120}
121
Geoff Langf6db0982015-08-25 13:04:00 -0400122void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
123{
Geoff Lang1a683462015-09-29 15:09:59 -0400124 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -0400125 {
126 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
127 tfBufferIndex++)
128 {
129 const OffsetBindingPointer<gl::Buffer> &buffer =
130 transformFeedback->getIndexedBuffer(tfBufferIndex);
131 if (buffer.get() != nullptr)
132 {
133 buffer->onTransformFeedback();
134 }
135 }
136 }
137}
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138
139// Attribute map queries.
140EGLint GetClientVersion(const egl::AttributeMap &attribs)
141{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400142 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500143}
144
145GLenum GetResetStrategy(const egl::AttributeMap &attribs)
146{
Ian Ewellec2c0c52016-04-05 13:46:26 -0400147 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
148 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149 switch (attrib)
150 {
151 case EGL_NO_RESET_NOTIFICATION:
152 return GL_NO_RESET_NOTIFICATION_EXT;
153 case EGL_LOSE_CONTEXT_ON_RESET:
154 return GL_LOSE_CONTEXT_ON_RESET_EXT;
155 default:
156 UNREACHABLE();
157 return GL_NONE;
158 }
159}
160
161bool GetRobustAccess(const egl::AttributeMap &attribs)
162{
163 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
164}
165
166bool GetDebug(const egl::AttributeMap &attribs)
167{
168 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
169}
170
171bool GetNoError(const egl::AttributeMap &attribs)
172{
173 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
174}
175
Geoff Langf6db0982015-08-25 13:04:00 -0400176} // anonymous namespace
177
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000178namespace gl
179{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000180
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400181Context::Context(rx::EGLImplFactory *implFactory,
182 const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400183 const Context *shareContext,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500184 const egl::AttributeMap &attribs)
185 : ValidationContext(GetClientVersion(attribs),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700186 &mGLState,
Jamie Madillf25855c2015-11-03 11:06:18 -0500187 mCaps,
188 mTextureCaps,
189 mExtensions,
190 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500191 mLimitations,
192 GetNoError(attribs)),
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700193 mImplementation(implFactory->createContext(mState)),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500194 mCompiler(nullptr),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500195 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400196 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500197 mClientType(EGL_OPENGL_ES_API),
198 mHasBeenCurrent(false),
199 mContextLost(false),
200 mResetStatus(GL_NO_ERROR),
201 mResetStrategy(GetResetStrategy(attribs)),
202 mRobustAccess(GetRobustAccess(attribs)),
203 mCurrentSurface(nullptr),
204 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500206 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000207
Jamie Madill00ed7a12016-05-19 13:13:38 -0400208 initCaps();
Geoff Langc0b9ef42014-07-02 10:02:37 -0400209
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700210 mGLState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100211
Shannon Woods53a94a82014-06-24 15:20:36 -0400212 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400213
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400214 if (shareContext != nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000215 {
216 mResourceManager = shareContext->mResourceManager;
217 mResourceManager->addRef();
218 }
219 else
220 {
Jamie Madill901b3792016-05-26 09:20:40 -0400221 mResourceManager = new ResourceManager();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000222 }
223
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700224 mState.mResourceManager = mResourceManager;
Jamie Madillc185cb82015-04-28 12:39:08 -0400225
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000226 // [OpenGL ES 2.0.24] section 3.7 page 83:
227 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
228 // and cube map texture state vectors respectively associated with them.
229 // In order that access to these initial textures not be lost, they are treated as texture
230 // objects all of whose names are 0.
231
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400232 Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500233 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500234
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400235 Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500236 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400237
238 if (mClientVersion >= 3)
239 {
240 // TODO: These could also be enabled via extension
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400241 Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500242 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400243
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400244 Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500245 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400246 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000247
Ian Ewellbda75592016-04-18 17:25:54 -0400248 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
249 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400250 Texture *zeroTextureExternal =
251 new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES);
Ian Ewellbda75592016-04-18 17:25:54 -0400252 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
253 }
254
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700255 mGLState.initializeZeroTextures(mZeroTextures);
Jamie Madille6382c32014-11-07 15:05:26 -0500256
Jamie Madill57a89722013-07-02 11:57:03 -0400257 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000258 bindArrayBuffer(0);
259 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400260
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000261 bindRenderbuffer(0);
262
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000263 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400264 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000265 {
266 bindIndexedUniformBuffer(0, i, 0, -1);
267 }
268
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000269 bindCopyReadBuffer(0);
270 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000271 bindPixelPackBuffer(0);
272 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000273
Geoff Lang1a683462015-09-29 15:09:59 -0400274 if (mClientVersion >= 3)
275 {
276 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
277 // In the initial state, a default transform feedback object is bound and treated as
278 // a transform feedback object with a name of zero. That object is bound any time
279 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400280 bindTransformFeedback(0);
281 }
Geoff Langc8058452014-02-03 12:04:11 -0500282
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700283 mCompiler = new Compiler(mImplementation.get(), mState);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500284
285 // Initialize dirty bit masks
286 // TODO(jmadill): additional ES3 state
287 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
288 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
289 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
290 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
291 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
292 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400293 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500294 // No dirty objects.
295
296 // Readpixels uses the pack state and read FBO
297 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
298 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
299 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
300 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
301 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400302 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500303 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
304
305 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
306 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
307 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
308 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
309 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
310 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
311 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
312 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
313 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
314 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
315 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
316 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
317
318 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
319 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
320 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
321 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400322
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400323 handleError(mImplementation->initialize());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000324}
325
326Context::~Context()
327{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700328 mGLState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000329
Corentin Wallez37c39792015-08-20 14:19:46 -0400330 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000331 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400332 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400333 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400334 {
335 SafeDelete(framebuffer.second);
336 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000337 }
338
Corentin Wallez80b24112015-08-25 16:41:57 -0400339 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000340 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400341 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000342 }
343
Corentin Wallez80b24112015-08-25 16:41:57 -0400344 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000345 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400346 if (query.second != nullptr)
347 {
348 query.second->release();
349 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000350 }
351
Corentin Wallez80b24112015-08-25 16:41:57 -0400352 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400353 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400354 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400355 }
356
Corentin Wallez80b24112015-08-25 16:41:57 -0400357 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500358 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500359 if (transformFeedback.second != nullptr)
360 {
361 transformFeedback.second->release();
362 }
Geoff Langc8058452014-02-03 12:04:11 -0500363 }
364
Jamie Madilldedd7b92014-11-05 16:30:36 -0500365 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400366 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500367 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400368 }
369 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370
Corentin Wallez51706ea2015-08-07 14:39:22 -0400371 if (mCurrentSurface != nullptr)
372 {
373 releaseSurface();
374 }
375
Jamie Madill1e9ae072014-11-06 15:27:21 -0500376 if (mResourceManager)
377 {
378 mResourceManager->release();
379 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500380
381 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000382}
383
daniel@transgaming.comad629872012-11-28 19:32:06 +0000384void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000385{
Jamie Madill77a72f62015-04-14 11:18:32 -0400386 ASSERT(surface != nullptr);
387
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000388 if (!mHasBeenCurrent)
389 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000390 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400391 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000392
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700393 mGLState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
394 mGLState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395
396 mHasBeenCurrent = true;
397 }
398
Jamie Madill1b94d432015-08-07 13:23:23 -0400399 // TODO(jmadill): Rework this when we support ContextImpl
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700400 mGLState.setAllDirtyBits();
Jamie Madill1b94d432015-08-07 13:23:23 -0400401
Corentin Wallez51706ea2015-08-07 14:39:22 -0400402 if (mCurrentSurface)
403 {
404 releaseSurface();
405 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000406 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400407 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000408
Corentin Wallez37c39792015-08-20 14:19:46 -0400409 // Update default framebuffer, the binding of the previous default
410 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400411 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400412 Framebuffer *newDefault = surface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700413 if (mGLState.getReadFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400414 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700415 mGLState.setReadFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400416 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700417 if (mGLState.getDrawFramebuffer() == nullptr)
Corentin Wallez37c39792015-08-20 14:19:46 -0400418 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700419 mGLState.setDrawFramebufferBinding(newDefault);
Corentin Wallez37c39792015-08-20 14:19:46 -0400420 }
421 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400422 }
Ian Ewell292f0052016-02-04 10:37:32 -0500423
424 // Notify the renderer of a context switch
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700425 mImplementation->onMakeCurrent(mState);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000426}
427
Jamie Madill77a72f62015-04-14 11:18:32 -0400428void Context::releaseSurface()
429{
Corentin Wallez37c39792015-08-20 14:19:46 -0400430 ASSERT(mCurrentSurface != nullptr);
431
432 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400433 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400434 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700435 if (mGLState.getReadFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400436 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700437 mGLState.setReadFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400438 }
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700439 if (mGLState.getDrawFramebuffer() == currentDefault)
Corentin Wallez37c39792015-08-20 14:19:46 -0400440 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700441 mGLState.setDrawFramebufferBinding(nullptr);
Corentin Wallez37c39792015-08-20 14:19:46 -0400442 }
443 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400444 }
445
Corentin Wallez51706ea2015-08-07 14:39:22 -0400446 mCurrentSurface->setIsCurrent(false);
447 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400448}
449
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000450// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000451void Context::markContextLost()
452{
453 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
454 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
455 mContextLost = true;
456}
457
458bool Context::isContextLost()
459{
460 return mContextLost;
461}
462
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463GLuint Context::createBuffer()
464{
465 return mResourceManager->createBuffer();
466}
467
468GLuint Context::createProgram()
469{
Jamie Madill901b3792016-05-26 09:20:40 -0400470 return mResourceManager->createProgram(mImplementation.get());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471}
472
473GLuint Context::createShader(GLenum type)
474{
Jamie Madill901b3792016-05-26 09:20:40 -0400475 return mResourceManager->createShader(mImplementation.get(),
476 mImplementation->getNativeLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000477}
478
479GLuint Context::createTexture()
480{
481 return mResourceManager->createTexture();
482}
483
484GLuint Context::createRenderbuffer()
485{
486 return mResourceManager->createRenderbuffer();
487}
488
Geoff Lang882033e2014-09-30 11:26:07 -0400489GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400490{
Jamie Madill901b3792016-05-26 09:20:40 -0400491 GLuint handle = mResourceManager->createFenceSync(mImplementation.get());
Jamie Madillcd055f82013-07-26 11:55:15 -0400492
Cooper Partind8e62a32015-01-29 15:21:25 -0800493 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400494}
495
Sami Väisänene45e53b2016-05-25 10:36:04 +0300496GLuint Context::createPaths(GLsizei range)
497{
498 auto resultOrError = mResourceManager->createPaths(mImplementation.get(), range);
499 if (resultOrError.isError())
500 {
501 handleError(resultOrError.getError());
502 return 0;
503 }
504 return resultOrError.getResult();
505}
506
Jamie Madill57a89722013-07-02 11:57:03 -0400507GLuint Context::createVertexArray()
508{
Geoff Lang36167ab2015-12-07 10:27:14 -0500509 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
510 mVertexArrayMap[vertexArray] = nullptr;
511 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400512}
513
Jamie Madilldc356042013-07-19 16:36:57 -0400514GLuint Context::createSampler()
515{
516 return mResourceManager->createSampler();
517}
518
Geoff Langc8058452014-02-03 12:04:11 -0500519GLuint Context::createTransformFeedback()
520{
Geoff Lang36167ab2015-12-07 10:27:14 -0500521 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
522 mTransformFeedbackMap[transformFeedback] = nullptr;
523 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500524}
525
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000526// Returns an unused framebuffer name
527GLuint Context::createFramebuffer()
528{
529 GLuint handle = mFramebufferHandleAllocator.allocate();
530
531 mFramebufferMap[handle] = NULL;
532
533 return handle;
534}
535
Jamie Madill33dc8432013-07-26 11:55:05 -0400536GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000537{
Jamie Madill33dc8432013-07-26 11:55:05 -0400538 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000539
Jamie Madill53ea9cc2016-05-17 10:12:52 -0400540 mFenceNVMap[handle] = new FenceNV(mImplementation->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000541
542 return handle;
543}
544
545// Returns an unused query name
546GLuint Context::createQuery()
547{
548 GLuint handle = mQueryHandleAllocator.allocate();
549
550 mQueryMap[handle] = NULL;
551
552 return handle;
553}
554
555void Context::deleteBuffer(GLuint buffer)
556{
557 if (mResourceManager->getBuffer(buffer))
558 {
559 detachBuffer(buffer);
560 }
Jamie Madill893ab082014-05-16 16:56:10 -0400561
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000562 mResourceManager->deleteBuffer(buffer);
563}
564
565void Context::deleteShader(GLuint shader)
566{
567 mResourceManager->deleteShader(shader);
568}
569
570void Context::deleteProgram(GLuint program)
571{
572 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000573}
574
575void Context::deleteTexture(GLuint texture)
576{
577 if (mResourceManager->getTexture(texture))
578 {
579 detachTexture(texture);
580 }
581
582 mResourceManager->deleteTexture(texture);
583}
584
585void Context::deleteRenderbuffer(GLuint renderbuffer)
586{
587 if (mResourceManager->getRenderbuffer(renderbuffer))
588 {
589 detachRenderbuffer(renderbuffer);
590 }
Jamie Madill893ab082014-05-16 16:56:10 -0400591
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000592 mResourceManager->deleteRenderbuffer(renderbuffer);
593}
594
Jamie Madillcd055f82013-07-26 11:55:15 -0400595void Context::deleteFenceSync(GLsync fenceSync)
596{
597 // The spec specifies the underlying Fence object is not deleted until all current
598 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
599 // and since our API is currently designed for being called from a single thread, we can delete
600 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700601 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400602}
603
Sami Väisänene45e53b2016-05-25 10:36:04 +0300604void Context::deletePaths(GLuint first, GLsizei range)
605{
606 mResourceManager->deletePaths(first, range);
607}
608
609bool Context::hasPathData(GLuint path) const
610{
611 const auto *pathObj = mResourceManager->getPath(path);
612 if (pathObj == nullptr)
613 return false;
614
615 return pathObj->hasPathData();
616}
617
618bool Context::hasPath(GLuint path) const
619{
620 return mResourceManager->hasPath(path);
621}
622
623void Context::setPathCommands(GLuint path,
624 GLsizei numCommands,
625 const GLubyte *commands,
626 GLsizei numCoords,
627 GLenum coordType,
628 const void *coords)
629{
630 auto *pathObject = mResourceManager->getPath(path);
631
632 handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords));
633}
634
635void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value)
636{
637 auto *pathObj = mResourceManager->getPath(path);
638
639 switch (pname)
640 {
641 case GL_PATH_STROKE_WIDTH_CHROMIUM:
642 pathObj->setStrokeWidth(value);
643 break;
644 case GL_PATH_END_CAPS_CHROMIUM:
645 pathObj->setEndCaps(static_cast<GLenum>(value));
646 break;
647 case GL_PATH_JOIN_STYLE_CHROMIUM:
648 pathObj->setJoinStyle(static_cast<GLenum>(value));
649 break;
650 case GL_PATH_MITER_LIMIT_CHROMIUM:
651 pathObj->setMiterLimit(value);
652 break;
653 case GL_PATH_STROKE_BOUND_CHROMIUM:
654 pathObj->setStrokeBound(value);
655 break;
656 default:
657 UNREACHABLE();
658 break;
659 }
660}
661
662void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const
663{
664 const auto *pathObj = mResourceManager->getPath(path);
665
666 switch (pname)
667 {
668 case GL_PATH_STROKE_WIDTH_CHROMIUM:
669 *value = pathObj->getStrokeWidth();
670 break;
671 case GL_PATH_END_CAPS_CHROMIUM:
672 *value = static_cast<GLfloat>(pathObj->getEndCaps());
673 break;
674 case GL_PATH_JOIN_STYLE_CHROMIUM:
675 *value = static_cast<GLfloat>(pathObj->getJoinStyle());
676 break;
677 case GL_PATH_MITER_LIMIT_CHROMIUM:
678 *value = pathObj->getMiterLimit();
679 break;
680 case GL_PATH_STROKE_BOUND_CHROMIUM:
681 *value = pathObj->getStrokeBound();
682 break;
683 default:
684 UNREACHABLE();
685 break;
686 }
687}
688
689void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
690{
691 mGLState.setPathStencilFunc(func, ref, mask);
692}
693
Jamie Madill57a89722013-07-02 11:57:03 -0400694void Context::deleteVertexArray(GLuint vertexArray)
695{
Geoff Lang36167ab2015-12-07 10:27:14 -0500696 auto iter = mVertexArrayMap.find(vertexArray);
697 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000698 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500699 VertexArray *vertexArrayObject = iter->second;
700 if (vertexArrayObject != nullptr)
701 {
702 detachVertexArray(vertexArray);
703 delete vertexArrayObject;
704 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000705
Geoff Lang36167ab2015-12-07 10:27:14 -0500706 mVertexArrayMap.erase(iter);
707 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400708 }
709}
710
Jamie Madilldc356042013-07-19 16:36:57 -0400711void Context::deleteSampler(GLuint sampler)
712{
713 if (mResourceManager->getSampler(sampler))
714 {
715 detachSampler(sampler);
716 }
717
718 mResourceManager->deleteSampler(sampler);
719}
720
Geoff Langc8058452014-02-03 12:04:11 -0500721void Context::deleteTransformFeedback(GLuint transformFeedback)
722{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500723 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500724 if (iter != mTransformFeedbackMap.end())
725 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500726 TransformFeedback *transformFeedbackObject = iter->second;
727 if (transformFeedbackObject != nullptr)
728 {
729 detachTransformFeedback(transformFeedback);
730 transformFeedbackObject->release();
731 }
732
Geoff Lang50b3fe82015-12-08 14:49:12 +0000733 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500734 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500735 }
736}
737
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000738void Context::deleteFramebuffer(GLuint framebuffer)
739{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500740 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000741
742 if (framebufferObject != mFramebufferMap.end())
743 {
744 detachFramebuffer(framebuffer);
745
746 mFramebufferHandleAllocator.release(framebufferObject->first);
747 delete framebufferObject->second;
748 mFramebufferMap.erase(framebufferObject);
749 }
750}
751
Jamie Madill33dc8432013-07-26 11:55:05 -0400752void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000753{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500754 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000755
Jamie Madill33dc8432013-07-26 11:55:05 -0400756 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000757 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400758 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000759 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400760 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000761 }
762}
763
764void Context::deleteQuery(GLuint query)
765{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500766 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000767 if (queryObject != mQueryMap.end())
768 {
769 mQueryHandleAllocator.release(queryObject->first);
770 if (queryObject->second)
771 {
772 queryObject->second->release();
773 }
774 mQueryMap.erase(queryObject);
775 }
776}
777
Geoff Lang70d0f492015-12-10 17:45:46 -0500778Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779{
780 return mResourceManager->getBuffer(handle);
781}
782
Geoff Lang48dcae72014-02-05 16:28:24 -0500783Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784{
785 return mResourceManager->getShader(handle);
786}
787
Geoff Lang48dcae72014-02-05 16:28:24 -0500788Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000789{
790 return mResourceManager->getProgram(handle);
791}
792
Jamie Madill570f7c82014-07-03 10:38:54 -0400793Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
795 return mResourceManager->getTexture(handle);
796}
797
Geoff Lang70d0f492015-12-10 17:45:46 -0500798Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000799{
800 return mResourceManager->getRenderbuffer(handle);
801}
802
Jamie Madillcd055f82013-07-26 11:55:15 -0400803FenceSync *Context::getFenceSync(GLsync handle) const
804{
Minmin Gong794e0002015-04-07 18:31:54 -0700805 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400806}
807
Jamie Madill57a89722013-07-02 11:57:03 -0400808VertexArray *Context::getVertexArray(GLuint handle) const
809{
810 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500811 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400812}
813
Jamie Madilldc356042013-07-19 16:36:57 -0400814Sampler *Context::getSampler(GLuint handle) const
815{
816 return mResourceManager->getSampler(handle);
817}
818
Geoff Langc8058452014-02-03 12:04:11 -0500819TransformFeedback *Context::getTransformFeedback(GLuint handle) const
820{
Geoff Lang36167ab2015-12-07 10:27:14 -0500821 auto iter = mTransformFeedbackMap.find(handle);
822 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500823}
824
Geoff Lang70d0f492015-12-10 17:45:46 -0500825LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
826{
827 switch (identifier)
828 {
829 case GL_BUFFER:
830 return getBuffer(name);
831 case GL_SHADER:
832 return getShader(name);
833 case GL_PROGRAM:
834 return getProgram(name);
835 case GL_VERTEX_ARRAY:
836 return getVertexArray(name);
837 case GL_QUERY:
838 return getQuery(name);
839 case GL_TRANSFORM_FEEDBACK:
840 return getTransformFeedback(name);
841 case GL_SAMPLER:
842 return getSampler(name);
843 case GL_TEXTURE:
844 return getTexture(name);
845 case GL_RENDERBUFFER:
846 return getRenderbuffer(name);
847 case GL_FRAMEBUFFER:
848 return getFramebuffer(name);
849 default:
850 UNREACHABLE();
851 return nullptr;
852 }
853}
854
855LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
856{
857 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
858}
859
Jamie Madilldc356042013-07-19 16:36:57 -0400860bool Context::isSampler(GLuint samplerName) const
861{
862 return mResourceManager->isSampler(samplerName);
863}
864
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500865void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000866{
Jamie Madill901b3792016-05-26 09:20:40 -0400867 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700868 mGLState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000869}
870
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500871void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872{
Jamie Madill901b3792016-05-26 09:20:40 -0400873 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700874 mGLState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000875}
876
Jamie Madilldedd7b92014-11-05 16:30:36 -0500877void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000878{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500879 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880
Jamie Madilldedd7b92014-11-05 16:30:36 -0500881 if (handle == 0)
882 {
883 texture = mZeroTextures[target].get();
884 }
885 else
886 {
Jamie Madill901b3792016-05-26 09:20:40 -0400887 texture = mResourceManager->checkTextureAllocation(mImplementation.get(), handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500888 }
889
890 ASSERT(texture);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700891 mGLState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000892}
893
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500894void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000895{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500896 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700897 mGLState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000898}
899
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500900void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000901{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500902 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700903 mGLState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000904}
905
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500906void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000907{
Jamie Madill901b3792016-05-26 09:20:40 -0400908 Renderbuffer *renderbuffer =
909 mResourceManager->checkRenderbufferAllocation(mImplementation.get(), renderbufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700910 mGLState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000911}
912
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500913void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400914{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500915 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700916 mGLState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400917}
918
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500919void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400920{
Geoff Lang76b10c92014-09-05 16:28:14 -0400921 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill901b3792016-05-26 09:20:40 -0400922 Sampler *sampler =
923 mResourceManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700924 mGLState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400925}
926
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500927void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000928{
Jamie Madill901b3792016-05-26 09:20:40 -0400929 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700930 mGLState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000931}
932
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500933void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
934 GLuint index,
935 GLintptr offset,
936 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000937{
Jamie Madill901b3792016-05-26 09:20:40 -0400938 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700939 mGLState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000940}
941
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500942void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000943{
Jamie Madill901b3792016-05-26 09:20:40 -0400944 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700945 mGLState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000946}
947
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500948void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
949 GLuint index,
950 GLintptr offset,
951 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000952{
Jamie Madill901b3792016-05-26 09:20:40 -0400953 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700954 mGLState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000955}
956
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500957void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000958{
Jamie Madill901b3792016-05-26 09:20:40 -0400959 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700960 mGLState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000961}
962
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500963void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000964{
Jamie Madill901b3792016-05-26 09:20:40 -0400965 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700966 mGLState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000967}
968
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500969void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000970{
Jamie Madill901b3792016-05-26 09:20:40 -0400971 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700972 mGLState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000973}
974
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500975void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000976{
Jamie Madill901b3792016-05-26 09:20:40 -0400977 Buffer *buffer = mResourceManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700978 mGLState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000979}
980
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981void Context::useProgram(GLuint program)
982{
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700983 mGLState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000984}
985
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500986void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500987{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500988 TransformFeedback *transformFeedback =
989 checkTransformFeedbackAllocation(transformFeedbackHandle);
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700990 mGLState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500991}
992
Geoff Lang5aad9672014-09-08 11:10:42 -0400993Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400996 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997
Geoff Lang5aad9672014-09-08 11:10:42 -0400998 // begin query
999 Error error = queryObject->begin();
1000 if (error.isError())
1001 {
1002 return error;
1003 }
1004
1005 // set query as active for specified target only if begin succeeded
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001006 mGLState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001007
Geoff Lang5aad9672014-09-08 11:10:42 -04001008 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001009}
1010
Geoff Lang5aad9672014-09-08 11:10:42 -04001011Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001012{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001013 Query *queryObject = mGLState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001014 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001015
Geoff Lang5aad9672014-09-08 11:10:42 -04001016 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001017
Geoff Lang5aad9672014-09-08 11:10:42 -04001018 // Always unbind the query, even if there was an error. This may delete the query object.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001019 mGLState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -04001020
1021 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022}
1023
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001024Error Context::queryCounter(GLuint id, GLenum target)
1025{
1026 ASSERT(target == GL_TIMESTAMP_EXT);
1027
1028 Query *queryObject = getQuery(id, true, target);
1029 ASSERT(queryObject);
1030
1031 return queryObject->queryCounter();
1032}
1033
1034void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
1035{
1036 switch (pname)
1037 {
1038 case GL_CURRENT_QUERY_EXT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001039 params[0] = mGLState.getActiveQueryId(target);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001040 break;
1041 case GL_QUERY_COUNTER_BITS_EXT:
1042 switch (target)
1043 {
1044 case GL_TIME_ELAPSED_EXT:
1045 params[0] = getExtensions().queryCounterBitsTimeElapsed;
1046 break;
1047 case GL_TIMESTAMP_EXT:
1048 params[0] = getExtensions().queryCounterBitsTimestamp;
1049 break;
1050 default:
1051 UNREACHABLE();
1052 params[0] = 0;
1053 break;
1054 }
1055 break;
1056 default:
1057 UNREACHABLE();
1058 return;
1059 }
1060}
1061
1062Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
1063{
1064 return GetQueryObjectParameter(this, id, pname, params);
1065}
1066
1067Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
1068{
1069 return GetQueryObjectParameter(this, id, pname, params);
1070}
1071
1072Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
1073{
1074 return GetQueryObjectParameter(this, id, pname, params);
1075}
1076
1077Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
1078{
1079 return GetQueryObjectParameter(this, id, pname, params);
1080}
1081
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001082Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001083{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001084 auto framebufferIt = mFramebufferMap.find(handle);
1085 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001086}
1087
Jamie Madill33dc8432013-07-26 11:55:05 -04001088FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001090 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091
Jamie Madill33dc8432013-07-26 11:55:05 -04001092 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001093 {
1094 return NULL;
1095 }
1096 else
1097 {
1098 return fence->second;
1099 }
1100}
1101
1102Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1103{
Jamie Madill4e25a0d2016-03-08 13:53:03 -05001104 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001105
1106 if (query == mQueryMap.end())
1107 {
1108 return NULL;
1109 }
1110 else
1111 {
1112 if (!query->second && create)
1113 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001114 query->second = new Query(mImplementation->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 query->second->addRef();
1116 }
1117 return query->second;
1118 }
1119}
1120
Geoff Lang70d0f492015-12-10 17:45:46 -05001121Query *Context::getQuery(GLuint handle) const
1122{
1123 auto iter = mQueryMap.find(handle);
1124 return (iter != mQueryMap.end()) ? iter->second : nullptr;
1125}
1126
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001127Texture *Context::getTargetTexture(GLenum target) const
1128{
Ian Ewellbda75592016-04-18 17:25:54 -04001129 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001130 return mGLState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001131}
1132
Geoff Lang76b10c92014-09-05 16:28:14 -04001133Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001134{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001135 return mGLState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001136}
1137
Geoff Lang492a7e42014-11-05 13:27:06 -05001138Compiler *Context::getCompiler() const
1139{
1140 return mCompiler;
1141}
1142
Jamie Madill893ab082014-05-16 16:56:10 -04001143void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001144{
1145 switch (pname)
1146 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001147 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001148 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001150 mGLState.getBooleanv(pname, params);
1151 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001152 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001153}
1154
Jamie Madill893ab082014-05-16 16:56:10 -04001155void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001156{
Shannon Woods53a94a82014-06-24 15:20:36 -04001157 // Queries about context capabilities and maximums are answered by Context.
1158 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001159 switch (pname)
1160 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001162 params[0] = mCaps.minAliasedLineWidth;
1163 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164 break;
1165 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001166 params[0] = mCaps.minAliasedPointSize;
1167 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001169 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001170 ASSERT(mExtensions.textureFilterAnisotropic);
1171 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001172 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001173 case GL_MAX_TEXTURE_LOD_BIAS:
1174 *params = mCaps.maxLODBias;
1175 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03001176
1177 case GL_PATH_MODELVIEW_MATRIX_CHROMIUM:
1178 case GL_PATH_PROJECTION_MATRIX_CHROMIUM:
1179 {
1180 ASSERT(mExtensions.pathRendering);
1181 const GLfloat *m = mGLState.getPathRenderingMatrix(pname);
1182 memcpy(params, m, 16 * sizeof(GLfloat));
1183 }
1184 break;
1185
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001186 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001187 mGLState.getFloatv(pname, params);
1188 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190}
1191
Jamie Madill893ab082014-05-16 16:56:10 -04001192void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193{
Shannon Woods53a94a82014-06-24 15:20:36 -04001194 // Queries about context capabilities and maximums are answered by Context.
1195 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001196
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001197 switch (pname)
1198 {
Geoff Lang301d1612014-07-09 10:34:37 -04001199 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1200 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1201 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001202 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1203 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1204 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001205 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1206 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1207 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001208 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001209 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1210 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1211 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001212 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001213 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001214 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1215 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1216 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1217 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001218 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1219 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001220 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1221 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001222 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001223 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1224 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1225 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1226 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001227 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1228 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001229 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1230 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001231 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1232 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1233 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001234 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1235 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1236 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001237 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001238 case GL_MAX_VIEWPORT_DIMS:
1239 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001240 params[0] = mCaps.maxViewportWidth;
1241 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 }
1243 break;
1244 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001245 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001246 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001247 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1248 *params = mResetStrategy;
1249 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001250 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001251 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001253 case GL_SHADER_BINARY_FORMATS:
1254 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1255 break;
1256 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001257 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001258 break;
1259 case GL_PROGRAM_BINARY_FORMATS:
1260 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001262 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001263 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001264 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001265
1266 // GL_KHR_debug
1267 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1268 *params = mExtensions.maxDebugMessageLength;
1269 break;
1270 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1271 *params = mExtensions.maxDebugLoggedMessages;
1272 break;
1273 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1274 *params = mExtensions.maxDebugGroupStackDepth;
1275 break;
1276 case GL_MAX_LABEL_LENGTH:
1277 *params = mExtensions.maxLabelLength;
1278 break;
1279
Ian Ewell53f59f42016-01-28 17:36:55 -05001280 // GL_EXT_disjoint_timer_query
1281 case GL_GPU_DISJOINT_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001282 *params = mImplementation->getGPUDisjoint();
Ian Ewell53f59f42016-01-28 17:36:55 -05001283 break;
1284
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001285 default:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001286 mGLState.getIntegerv(mState, pname, params);
1287 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001288 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001289}
1290
Jamie Madill893ab082014-05-16 16:56:10 -04001291void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001292{
Shannon Woods53a94a82014-06-24 15:20:36 -04001293 // Queries about context capabilities and maximums are answered by Context.
1294 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001295 switch (pname)
1296 {
1297 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001298 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001299 break;
1300 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001301 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001302 break;
1303 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001304 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001305 break;
1306 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001307 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001308 break;
1309 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001310 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001311 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001312
1313 // GL_EXT_disjoint_timer_query
1314 case GL_TIMESTAMP_EXT:
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001315 *params = mImplementation->getTimestamp();
Ian Ewell53f59f42016-01-28 17:36:55 -05001316 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001317 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001318 UNREACHABLE();
1319 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001320 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001321}
1322
Geoff Lang70d0f492015-12-10 17:45:46 -05001323void Context::getPointerv(GLenum pname, void **params) const
1324{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001325 mGLState.getPointerv(pname, params);
Geoff Lang70d0f492015-12-10 17:45:46 -05001326}
1327
Shannon Woods1b2fb852013-08-19 14:28:48 -04001328bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1329{
Shannon Woods53a94a82014-06-24 15:20:36 -04001330 // Queries about context capabilities and maximums are answered by Context.
1331 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001332 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001333 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001334 return mGLState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001335}
1336
1337bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1338{
Shannon Woods53a94a82014-06-24 15:20:36 -04001339 // Queries about context capabilities and maximums are answered by Context.
1340 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001341 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001342 // mere passthrough.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001343 return mGLState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001344}
1345
Geoff Langf6db0982015-08-25 13:04:00 -04001346Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001347{
Jamie Madill1b94d432015-08-07 13:23:23 -04001348 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001349 ANGLE_TRY(mImplementation->drawArrays(mode, first, count));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001350 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001351
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001352 return NoError();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353}
1354
Geoff Langf6db0982015-08-25 13:04:00 -04001355Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1356{
1357 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001358 ANGLE_TRY(mImplementation->drawArraysInstanced(mode, first, count, instanceCount));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001359 MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
Geoff Langf6db0982015-08-25 13:04:00 -04001360
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001361 return NoError();
Geoff Langf6db0982015-08-25 13:04:00 -04001362}
1363
1364Error Context::drawElements(GLenum mode,
1365 GLsizei count,
1366 GLenum type,
1367 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001368 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001369{
Jamie Madill1b94d432015-08-07 13:23:23 -04001370 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001371 return mImplementation->drawElements(mode, count, type, indices, indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001372}
1373
1374Error Context::drawElementsInstanced(GLenum mode,
1375 GLsizei count,
1376 GLenum type,
1377 const GLvoid *indices,
1378 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001379 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001380{
1381 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001382 return mImplementation->drawElementsInstanced(mode, count, type, indices, instances,
1383 indexRange);
Geoff Langf6db0982015-08-25 13:04:00 -04001384}
1385
1386Error Context::drawRangeElements(GLenum mode,
1387 GLuint start,
1388 GLuint end,
1389 GLsizei count,
1390 GLenum type,
1391 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001392 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001393{
1394 syncRendererState();
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001395 return mImplementation->drawRangeElements(mode, start, end, count, type, indices, indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001396}
1397
Geoff Lang129753a2015-01-09 16:52:09 -05001398Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001399{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001400 return mImplementation->flush();
Geoff Lang129753a2015-01-09 16:52:09 -05001401}
1402
1403Error Context::finish()
1404{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001405 return mImplementation->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001406}
1407
Austin Kinross6ee1e782015-05-29 17:05:37 -07001408void Context::insertEventMarker(GLsizei length, const char *marker)
1409{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001410 ASSERT(mImplementation);
1411 mImplementation->insertEventMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001412}
1413
1414void Context::pushGroupMarker(GLsizei length, const char *marker)
1415{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001416 ASSERT(mImplementation);
1417 mImplementation->pushGroupMarker(length, marker);
Austin Kinross6ee1e782015-05-29 17:05:37 -07001418}
1419
1420void Context::popGroupMarker()
1421{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001422 ASSERT(mImplementation);
1423 mImplementation->popGroupMarker();
Austin Kinross6ee1e782015-05-29 17:05:37 -07001424}
1425
Geoff Langd8605522016-04-13 10:19:12 -04001426void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1427{
1428 Program *programObject = getProgram(program);
1429 ASSERT(programObject);
1430
1431 programObject->bindUniformLocation(location, name);
1432}
1433
Sami Väisänena797e062016-05-12 15:23:40 +03001434void Context::setCoverageModulation(GLenum components)
1435{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001436 mGLState.setCoverageModulation(components);
Sami Väisänena797e062016-05-12 15:23:40 +03001437}
1438
Sami Väisänene45e53b2016-05-25 10:36:04 +03001439void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1440{
1441 mGLState.loadPathRenderingMatrix(matrixMode, matrix);
1442}
1443
1444void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode)
1445{
1446 GLfloat I[16];
1447 angle::Matrix<GLfloat>::setToIdentity(I);
1448
1449 mGLState.loadPathRenderingMatrix(matrixMode, I);
1450}
1451
1452void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask)
1453{
1454 const auto *pathObj = mResourceManager->getPath(path);
1455 if (!pathObj)
1456 return;
1457
1458 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1459 syncRendererState();
1460
1461 mImplementation->stencilFillPath(pathObj, fillMode, mask);
1462}
1463
1464void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask)
1465{
1466 const auto *pathObj = mResourceManager->getPath(path);
1467 if (!pathObj)
1468 return;
1469
1470 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1471 syncRendererState();
1472
1473 mImplementation->stencilStrokePath(pathObj, reference, mask);
1474}
1475
1476void Context::coverFillPath(GLuint path, GLenum coverMode)
1477{
1478 const auto *pathObj = mResourceManager->getPath(path);
1479 if (!pathObj)
1480 return;
1481
1482 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1483 syncRendererState();
1484
1485 mImplementation->coverFillPath(pathObj, coverMode);
1486}
1487
1488void Context::coverStrokePath(GLuint path, GLenum coverMode)
1489{
1490 const auto *pathObj = mResourceManager->getPath(path);
1491 if (!pathObj)
1492 return;
1493
1494 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1495 syncRendererState();
1496
1497 mImplementation->coverStrokePath(pathObj, coverMode);
1498}
1499
1500void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)
1501{
1502 const auto *pathObj = mResourceManager->getPath(path);
1503 if (!pathObj)
1504 return;
1505
1506 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1507 syncRendererState();
1508
1509 mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode);
1510}
1511
1512void Context::stencilThenCoverStrokePath(GLuint path,
1513 GLint reference,
1514 GLuint mask,
1515 GLenum coverMode)
1516{
1517 const auto *pathObj = mResourceManager->getPath(path);
1518 if (!pathObj)
1519 return;
1520
1521 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1522 syncRendererState();
1523
1524 mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode);
1525}
1526
Sami Väisänend59ca052016-06-21 16:10:00 +03001527void Context::coverFillPathInstanced(GLsizei numPaths,
1528 GLenum pathNameType,
1529 const void *paths,
1530 GLuint pathBase,
1531 GLenum coverMode,
1532 GLenum transformType,
1533 const GLfloat *transformValues)
1534{
1535 const auto &pathObjects =
1536 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1537
1538 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1539 syncRendererState();
1540
1541 mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues);
1542}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001543
Sami Väisänend59ca052016-06-21 16:10:00 +03001544void Context::coverStrokePathInstanced(GLsizei numPaths,
1545 GLenum pathNameType,
1546 const void *paths,
1547 GLuint pathBase,
1548 GLenum coverMode,
1549 GLenum transformType,
1550 const GLfloat *transformValues)
1551{
1552 const auto &pathObjects =
1553 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1554
1555 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1556 syncRendererState();
1557
1558 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1559 transformValues);
1560}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001561
Sami Väisänend59ca052016-06-21 16:10:00 +03001562void Context::stencilFillPathInstanced(GLsizei numPaths,
1563 GLenum pathNameType,
1564 const void *paths,
1565 GLuint pathBase,
1566 GLenum fillMode,
1567 GLuint mask,
1568 GLenum transformType,
1569 const GLfloat *transformValues)
1570{
1571 const auto &pathObjects =
1572 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1573
1574 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1575 syncRendererState();
1576
1577 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1578 transformValues);
1579}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001580
Sami Väisänend59ca052016-06-21 16:10:00 +03001581void Context::stencilStrokePathInstanced(GLsizei numPaths,
1582 GLenum pathNameType,
1583 const void *paths,
1584 GLuint pathBase,
1585 GLint reference,
1586 GLuint mask,
1587 GLenum transformType,
1588 const GLfloat *transformValues)
1589{
1590 const auto &pathObjects =
1591 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1592
1593 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1594 syncRendererState();
1595
1596 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1597 transformValues);
1598}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001599
Sami Väisänend59ca052016-06-21 16:10:00 +03001600void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1601 GLenum pathNameType,
1602 const void *paths,
1603 GLuint pathBase,
1604 GLenum fillMode,
1605 GLuint mask,
1606 GLenum coverMode,
1607 GLenum transformType,
1608 const GLfloat *transformValues)
1609{
1610 const auto &pathObjects =
1611 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1612
1613 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1614 syncRendererState();
1615
1616 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1617 transformType, transformValues);
1618}
Sami Väisänen46eaa942016-06-29 10:26:37 +03001619
Sami Väisänend59ca052016-06-21 16:10:00 +03001620void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1621 GLenum pathNameType,
1622 const void *paths,
1623 GLuint pathBase,
1624 GLint reference,
1625 GLuint mask,
1626 GLenum coverMode,
1627 GLenum transformType,
1628 const GLfloat *transformValues)
1629{
1630 const auto &pathObjects =
1631 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1632
1633 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1634 syncRendererState();
1635
1636 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1637 transformType, transformValues);
1638}
1639
Sami Väisänen46eaa942016-06-29 10:26:37 +03001640void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
1641{
1642 auto *programObject = getProgram(program);
1643
1644 programObject->bindFragmentInputLocation(location, name);
1645}
1646
1647void Context::programPathFragmentInputGen(GLuint program,
1648 GLint location,
1649 GLenum genMode,
1650 GLint components,
1651 const GLfloat *coeffs)
1652{
1653 auto *programObject = getProgram(program);
1654
1655 programObject->pathFragmentInputGen(location, genMode, components, coeffs);
1656}
1657
Jamie Madill437fa652016-05-03 15:13:24 -04001658void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659{
Geoff Langda5777c2014-07-11 09:52:58 -04001660 if (error.isError())
1661 {
1662 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001663
1664 if (!error.getMessage().empty())
1665 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001666 auto *debug = &mGLState.getDebug();
1667 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1668 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001669 }
Geoff Langda5777c2014-07-11 09:52:58 -04001670 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001671}
1672
1673// Get one of the recorded errors and clear its flag, if any.
1674// [OpenGL ES 2.0.24] section 2.5 page 13.
1675GLenum Context::getError()
1676{
Geoff Langda5777c2014-07-11 09:52:58 -04001677 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001678 {
Geoff Langda5777c2014-07-11 09:52:58 -04001679 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001680 }
Geoff Langda5777c2014-07-11 09:52:58 -04001681 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682 {
Geoff Langda5777c2014-07-11 09:52:58 -04001683 GLenum error = *mErrors.begin();
1684 mErrors.erase(mErrors.begin());
1685 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687}
1688
1689GLenum Context::getResetStatus()
1690{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001691 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001692 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001694 // mResetStatus will be set by the markContextLost callback
1695 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001696 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001697 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001698 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001699 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001700 }
1701
1702 GLenum status = mResetStatus;
1703
1704 if (mResetStatus != GL_NO_ERROR)
1705 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001706 ASSERT(mContextLost);
1707
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001708 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001709 {
1710 mResetStatus = GL_NO_ERROR;
1711 }
1712 }
Jamie Madill893ab082014-05-16 16:56:10 -04001713
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001714 return status;
1715}
1716
1717bool Context::isResetNotificationEnabled()
1718{
1719 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1720}
1721
Corentin Walleze3b10e82015-05-20 11:06:25 -04001722const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001723{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001724 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001725}
1726
1727EGLenum Context::getClientType() const
1728{
1729 return mClientType;
1730}
1731
1732EGLenum Context::getRenderBuffer() const
1733{
Corentin Wallez37c39792015-08-20 14:19:46 -04001734 auto framebufferIt = mFramebufferMap.find(0);
1735 if (framebufferIt != mFramebufferMap.end())
1736 {
1737 const Framebuffer *framebuffer = framebufferIt->second;
1738 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1739
1740 ASSERT(backAttachment != nullptr);
1741 return backAttachment->getSurface()->getRenderBuffer();
1742 }
1743 else
1744 {
1745 return EGL_NONE;
1746 }
Régis Fénéon83107972015-02-05 12:57:44 +01001747}
1748
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001749VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001750{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001751 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001752 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1753 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001754 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001755 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1756
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001757 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001758 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001759
1760 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001761}
1762
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001763TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001764{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001765 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001766 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1767 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001768 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001769 transformFeedback =
1770 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001771 transformFeedback->addRef();
1772 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001773 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001774
1775 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001776}
1777
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001778Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1779{
1780 // Can be called from Bind without a prior call to Gen.
1781 auto framebufferIt = mFramebufferMap.find(framebuffer);
1782 bool neverCreated = framebufferIt == mFramebufferMap.end();
1783 if (neverCreated || framebufferIt->second == nullptr)
1784 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001785 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001786 if (neverCreated)
1787 {
1788 mFramebufferHandleAllocator.reserve(framebuffer);
1789 mFramebufferMap[framebuffer] = newFBO;
1790 return newFBO;
1791 }
1792
1793 framebufferIt->second = newFBO;
1794 }
1795
1796 return framebufferIt->second;
1797}
1798
Geoff Lang36167ab2015-12-07 10:27:14 -05001799bool Context::isVertexArrayGenerated(GLuint vertexArray)
1800{
1801 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1802}
1803
1804bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1805{
1806 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1807}
1808
Shannon Woods53a94a82014-06-24 15:20:36 -04001809void Context::detachTexture(GLuint texture)
1810{
1811 // Simple pass-through to State's detachTexture method, as textures do not require
1812 // allocation map management either here or in the resource manager at detach time.
1813 // Zero textures are held by the Context, and we don't attempt to request them from
1814 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001815 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001816}
1817
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001818void Context::detachBuffer(GLuint buffer)
1819{
Yuly Novikov5807a532015-12-03 13:01:22 -05001820 // Simple pass-through to State's detachBuffer method, since
1821 // only buffer attachments to container objects that are bound to the current context
1822 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001823
Yuly Novikov5807a532015-12-03 13:01:22 -05001824 // [OpenGL ES 3.2] section 5.1.2 page 45:
1825 // Attachments to unbound container objects, such as
1826 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1827 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001828 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001829}
1830
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001831void Context::detachFramebuffer(GLuint framebuffer)
1832{
Shannon Woods53a94a82014-06-24 15:20:36 -04001833 // Framebuffer detachment is handled by Context, because 0 is a valid
1834 // Framebuffer object, and a pointer to it must be passed from Context
1835 // to State at binding time.
1836
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001837 // [OpenGL ES 2.0.24] section 4.4 page 107:
1838 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1839 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1840
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001841 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001842 {
1843 bindReadFramebuffer(0);
1844 }
1845
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001846 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847 {
1848 bindDrawFramebuffer(0);
1849 }
1850}
1851
1852void Context::detachRenderbuffer(GLuint renderbuffer)
1853{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001854 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001855}
1856
Jamie Madill57a89722013-07-02 11:57:03 -04001857void Context::detachVertexArray(GLuint vertexArray)
1858{
Jamie Madill77a72f62015-04-14 11:18:32 -04001859 // Vertex array detachment is handled by Context, because 0 is a valid
1860 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001861 // binding time.
1862
Jamie Madill57a89722013-07-02 11:57:03 -04001863 // [OpenGL ES 3.0.2] section 2.10 page 43:
1864 // If a vertex array object that is currently bound is deleted, the binding
1865 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001866 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001867 {
1868 bindVertexArray(0);
1869 }
1870}
1871
Geoff Langc8058452014-02-03 12:04:11 -05001872void Context::detachTransformFeedback(GLuint transformFeedback)
1873{
Corentin Walleza2257da2016-04-19 16:43:12 -04001874 // Transform feedback detachment is handled by Context, because 0 is a valid
1875 // transform feedback, and a pointer to it must be passed from Context to State at
1876 // binding time.
1877
1878 // The OpenGL specification doesn't mention what should happen when the currently bound
1879 // transform feedback object is deleted. Since it is a container object, we treat it like
1880 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001881 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04001882 {
1883 bindTransformFeedback(0);
1884 }
Geoff Langc8058452014-02-03 12:04:11 -05001885}
1886
Jamie Madilldc356042013-07-19 16:36:57 -04001887void Context::detachSampler(GLuint sampler)
1888{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001889 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001890}
1891
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001892void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1893{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001894 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001895}
1896
Jamie Madille29d1672013-07-19 16:36:57 -04001897void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1898{
Jamie Madill901b3792016-05-26 09:20:40 -04001899 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001900
1901 Sampler *samplerObject = getSampler(sampler);
1902 ASSERT(samplerObject);
1903
Geoff Lang69cce582015-09-17 13:20:36 -04001904 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001905 switch (pname)
1906 {
Geoff Lang69cce582015-09-17 13:20:36 -04001907 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1908 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1909 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1910 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1911 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1912 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1913 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1914 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1915 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1916 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1917 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001918 }
Geoff Lang69cce582015-09-17 13:20:36 -04001919 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001920}
1921
1922void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1923{
Jamie Madill901b3792016-05-26 09:20:40 -04001924 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001925
1926 Sampler *samplerObject = getSampler(sampler);
1927 ASSERT(samplerObject);
1928
Geoff Lang69cce582015-09-17 13:20:36 -04001929 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001930 switch (pname)
1931 {
Geoff Lang69cce582015-09-17 13:20:36 -04001932 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1933 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1934 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1935 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1936 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1937 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1938 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1939 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1940 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1941 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1942 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001943 }
Geoff Lang69cce582015-09-17 13:20:36 -04001944 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001945}
1946
Jamie Madill9675b802013-07-19 16:36:59 -04001947GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1948{
Jamie Madill901b3792016-05-26 09:20:40 -04001949 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001950
1951 Sampler *samplerObject = getSampler(sampler);
1952 ASSERT(samplerObject);
1953
Geoff Lang69cce582015-09-17 13:20:36 -04001954 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001955 switch (pname)
1956 {
Geoff Lang69cce582015-09-17 13:20:36 -04001957 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1958 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1959 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1960 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1961 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1962 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001963 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1964 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001965 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1966 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1967 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001968 }
Geoff Lang69cce582015-09-17 13:20:36 -04001969 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001970}
1971
1972GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1973{
Jamie Madill901b3792016-05-26 09:20:40 -04001974 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001975
1976 Sampler *samplerObject = getSampler(sampler);
1977 ASSERT(samplerObject);
1978
Geoff Lang69cce582015-09-17 13:20:36 -04001979 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001980 switch (pname)
1981 {
Geoff Lang69cce582015-09-17 13:20:36 -04001982 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1983 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1984 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1985 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1986 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1987 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1988 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1989 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1990 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1991 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1992 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001993 }
Geoff Lang69cce582015-09-17 13:20:36 -04001994 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001995}
1996
Olli Etuahof0fee072016-03-30 15:11:58 +03001997void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1998{
1999 gl::Program *programObject = getProgram(program);
2000 ASSERT(programObject != nullptr);
2001
2002 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2003 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2004}
2005
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002006void Context::initRendererString()
2007{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002008 std::ostringstream rendererString;
2009 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002010 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002011 rendererString << ")";
2012
Geoff Langcec35902014-04-16 10:52:36 -04002013 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002014}
2015
Geoff Langc0b9ef42014-07-02 10:02:37 -04002016const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002017{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002018 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002019}
2020
Geoff Langcec35902014-04-16 10:52:36 -04002021void Context::initExtensionStrings()
2022{
Geoff Lang493daf52014-07-03 13:38:44 -04002023 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002024
Geoff Langc0b9ef42014-07-02 10:02:37 -04002025 std::ostringstream combinedStringStream;
2026 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2027 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002028}
2029
Geoff Langc0b9ef42014-07-02 10:02:37 -04002030const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002031{
2032 return mExtensionString;
2033}
2034
Geoff Langc0b9ef42014-07-02 10:02:37 -04002035const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002036{
2037 return mExtensionStrings[idx];
2038}
2039
2040size_t Context::getExtensionStringCount() const
2041{
2042 return mExtensionStrings.size();
2043}
2044
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002045void Context::beginTransformFeedback(GLenum primitiveMode)
2046{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002047 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002048 ASSERT(transformFeedback != nullptr);
2049 ASSERT(!transformFeedback->isPaused());
2050
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002051 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002052}
2053
2054bool Context::hasActiveTransformFeedback(GLuint program) const
2055{
2056 for (auto pair : mTransformFeedbackMap)
2057 {
2058 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2059 {
2060 return true;
2061 }
2062 }
2063 return false;
2064}
2065
Jamie Madill00ed7a12016-05-19 13:13:38 -04002066void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002067{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002068 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002069
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002070 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002071
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002072 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002073
Jamie Madill00ed7a12016-05-19 13:13:38 -04002074 if (mClientVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002075 {
2076 // Disable ES3+ extensions
2077 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002078 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002079 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002080 }
2081
Jamie Madill00ed7a12016-05-19 13:13:38 -04002082 if (mClientVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002083 {
2084 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2085 //mExtensions.sRGB = false;
2086 }
2087
Jamie Madill00ed7a12016-05-19 13:13:38 -04002088 // Some extensions are always available because they are implemented in the GL layer.
2089 mExtensions.bindUniformLocation = true;
2090 mExtensions.vertexArrayObject = true;
2091
2092 // Enable the no error extension if the context was created with the flag.
2093 mExtensions.noError = mSkipValidation;
2094
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 // Explicitly enable GL_KHR_debug
2096 mExtensions.debug = true;
2097 mExtensions.maxDebugMessageLength = 1024;
2098 mExtensions.maxDebugLoggedMessages = 1024;
2099 mExtensions.maxDebugGroupStackDepth = 1024;
2100 mExtensions.maxLabelLength = 1024;
2101
Geoff Lang301d1612014-07-09 10:34:37 -04002102 // Apply implementation limits
2103 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002104 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2105 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2106
2107 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002108
Geoff Lang900013c2014-07-07 11:32:19 -04002109 mCaps.compressedTextureFormats.clear();
2110
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002111 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002112 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2113 {
2114 GLenum format = i->first;
2115 TextureCaps formatCaps = i->second;
2116
Geoff Lang5d601382014-07-22 15:14:06 -04002117 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002118
Geoff Lang0d8b7242015-09-09 14:56:53 -04002119 // Update the format caps based on the client version and extensions.
2120 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2121 // ES3.
2122 formatCaps.texturable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002123 formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002124 formatCaps.renderable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002125 formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002126 formatCaps.filterable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002127 formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002128
2129 // OpenGL ES does not support multisampling with integer formats
2130 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002131 {
Geoff Langd87878e2014-09-19 15:42:59 -04002132 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002133 }
Geoff Langd87878e2014-09-19 15:42:59 -04002134
2135 if (formatCaps.texturable && formatInfo.compressed)
2136 {
2137 mCaps.compressedTextureFormats.push_back(format);
2138 }
2139
2140 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002141 }
2142}
2143
Jamie Madill1b94d432015-08-07 13:23:23 -04002144void Context::syncRendererState()
2145{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002146 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2147 mImplementation->syncState(mGLState, dirtyBits);
2148 mGLState.clearDirtyBits();
2149 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002150}
2151
Jamie Madillad9f24e2016-02-12 09:27:24 -05002152void Context::syncRendererState(const State::DirtyBits &bitMask,
2153 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002154{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002155 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2156 mImplementation->syncState(mGLState, dirtyBits);
2157 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002158
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002159 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002160}
Jamie Madillc29968b2016-01-20 11:17:23 -05002161
2162void Context::blitFramebuffer(GLint srcX0,
2163 GLint srcY0,
2164 GLint srcX1,
2165 GLint srcY1,
2166 GLint dstX0,
2167 GLint dstY0,
2168 GLint dstX1,
2169 GLint dstY1,
2170 GLbitfield mask,
2171 GLenum filter)
2172{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002173 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002174 ASSERT(drawFramebuffer);
2175
2176 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2177 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2178
Jamie Madillad9f24e2016-02-12 09:27:24 -05002179 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002180
Jamie Madill8415b5f2016-04-26 13:41:39 -04002181 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002182}
Jamie Madillc29968b2016-01-20 11:17:23 -05002183
2184void Context::clear(GLbitfield mask)
2185{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002186 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002187 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002188}
2189
2190void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2191{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002192 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002193 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2194 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002195}
2196
2197void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2198{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002199 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002200 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2201 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002202}
2203
2204void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2205{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002206 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002207 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2208 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002209}
2210
2211void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2212{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002213 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002214 ASSERT(framebufferObject);
2215
2216 // If a buffer is not present, the clear has no effect
2217 if (framebufferObject->getDepthbuffer() == nullptr &&
2218 framebufferObject->getStencilbuffer() == nullptr)
2219 {
2220 return;
2221 }
2222
Jamie Madillad9f24e2016-02-12 09:27:24 -05002223 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002224 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2225 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002226}
2227
2228void Context::readPixels(GLint x,
2229 GLint y,
2230 GLsizei width,
2231 GLsizei height,
2232 GLenum format,
2233 GLenum type,
2234 GLvoid *pixels)
2235{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002236 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002237
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002238 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002239 ASSERT(framebufferObject);
2240
2241 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002242 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002243}
2244
2245void Context::copyTexImage2D(GLenum target,
2246 GLint level,
2247 GLenum internalformat,
2248 GLint x,
2249 GLint y,
2250 GLsizei width,
2251 GLsizei height,
2252 GLint border)
2253{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002254 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002255 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002256
Jamie Madillc29968b2016-01-20 11:17:23 -05002257 Rectangle sourceArea(x, y, width, height);
2258
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002259 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002260 Texture *texture =
2261 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002262 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002263}
2264
2265void Context::copyTexSubImage2D(GLenum target,
2266 GLint level,
2267 GLint xoffset,
2268 GLint yoffset,
2269 GLint x,
2270 GLint y,
2271 GLsizei width,
2272 GLsizei height)
2273{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002274 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002275 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002276
Jamie Madillc29968b2016-01-20 11:17:23 -05002277 Offset destOffset(xoffset, yoffset, 0);
2278 Rectangle sourceArea(x, y, width, height);
2279
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002280 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002281 Texture *texture =
2282 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002283 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002284}
2285
2286void Context::copyTexSubImage3D(GLenum target,
2287 GLint level,
2288 GLint xoffset,
2289 GLint yoffset,
2290 GLint zoffset,
2291 GLint x,
2292 GLint y,
2293 GLsizei width,
2294 GLsizei height)
2295{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002296 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002297 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002298
Jamie Madillc29968b2016-01-20 11:17:23 -05002299 Offset destOffset(xoffset, yoffset, zoffset);
2300 Rectangle sourceArea(x, y, width, height);
2301
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002302 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002303 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002304 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002305}
2306
2307void Context::framebufferTexture2D(GLenum target,
2308 GLenum attachment,
2309 GLenum textarget,
2310 GLuint texture,
2311 GLint level)
2312{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002313 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002314 ASSERT(framebuffer);
2315
2316 if (texture != 0)
2317 {
2318 Texture *textureObj = getTexture(texture);
2319
2320 ImageIndex index = ImageIndex::MakeInvalid();
2321
2322 if (textarget == GL_TEXTURE_2D)
2323 {
2324 index = ImageIndex::Make2D(level);
2325 }
2326 else
2327 {
2328 ASSERT(IsCubeMapTextureTarget(textarget));
2329 index = ImageIndex::MakeCube(textarget, level);
2330 }
2331
2332 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2333 }
2334 else
2335 {
2336 framebuffer->resetAttachment(attachment);
2337 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002338
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002339 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002340}
2341
2342void Context::framebufferRenderbuffer(GLenum target,
2343 GLenum attachment,
2344 GLenum renderbuffertarget,
2345 GLuint renderbuffer)
2346{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002347 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002348 ASSERT(framebuffer);
2349
2350 if (renderbuffer != 0)
2351 {
2352 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2353 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2354 renderbufferObject);
2355 }
2356 else
2357 {
2358 framebuffer->resetAttachment(attachment);
2359 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002360
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002361 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002362}
2363
2364void Context::framebufferTextureLayer(GLenum target,
2365 GLenum attachment,
2366 GLuint texture,
2367 GLint level,
2368 GLint layer)
2369{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002370 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002371 ASSERT(framebuffer);
2372
2373 if (texture != 0)
2374 {
2375 Texture *textureObject = getTexture(texture);
2376
2377 ImageIndex index = ImageIndex::MakeInvalid();
2378
2379 if (textureObject->getTarget() == GL_TEXTURE_3D)
2380 {
2381 index = ImageIndex::Make3D(level, layer);
2382 }
2383 else
2384 {
2385 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2386 index = ImageIndex::Make2DArray(level, layer);
2387 }
2388
2389 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2390 }
2391 else
2392 {
2393 framebuffer->resetAttachment(attachment);
2394 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002395
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002396 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002397}
2398
2399void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2400{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002401 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002402 ASSERT(framebuffer);
2403 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002404 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002405}
2406
2407void Context::readBuffer(GLenum mode)
2408{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002409 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002410 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002411 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002412}
2413
2414void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2415{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002416 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002417 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002418
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002419 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002420 ASSERT(framebuffer);
2421
2422 // The specification isn't clear what should be done when the framebuffer isn't complete.
2423 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002424 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002425}
2426
2427void Context::invalidateFramebuffer(GLenum target,
2428 GLsizei numAttachments,
2429 const GLenum *attachments)
2430{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002431 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002432 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002433
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002434 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002435 ASSERT(framebuffer);
2436
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002437 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002438 {
Jamie Madill437fa652016-05-03 15:13:24 -04002439 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 }
Jamie Madill437fa652016-05-03 15:13:24 -04002441
2442 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002443}
2444
2445void Context::invalidateSubFramebuffer(GLenum target,
2446 GLsizei numAttachments,
2447 const GLenum *attachments,
2448 GLint x,
2449 GLint y,
2450 GLsizei width,
2451 GLsizei height)
2452{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002453 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002454 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002455
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002456 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002457 ASSERT(framebuffer);
2458
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002459 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002460 {
Jamie Madill437fa652016-05-03 15:13:24 -04002461 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002462 }
Jamie Madill437fa652016-05-03 15:13:24 -04002463
2464 Rectangle area(x, y, width, height);
2465 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002466}
2467
Jamie Madill73a84962016-02-12 09:27:23 -05002468void Context::texImage2D(GLenum target,
2469 GLint level,
2470 GLint internalformat,
2471 GLsizei width,
2472 GLsizei height,
2473 GLint border,
2474 GLenum format,
2475 GLenum type,
2476 const GLvoid *pixels)
2477{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002478 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002479
2480 Extents size(width, height, 1);
2481 Texture *texture =
2482 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002483 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002484 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002485}
2486
2487void Context::texImage3D(GLenum target,
2488 GLint level,
2489 GLint internalformat,
2490 GLsizei width,
2491 GLsizei height,
2492 GLsizei depth,
2493 GLint border,
2494 GLenum format,
2495 GLenum type,
2496 const GLvoid *pixels)
2497{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002498 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002499
2500 Extents size(width, height, depth);
2501 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002502 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002503 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002504}
2505
2506void Context::texSubImage2D(GLenum target,
2507 GLint level,
2508 GLint xoffset,
2509 GLint yoffset,
2510 GLsizei width,
2511 GLsizei height,
2512 GLenum format,
2513 GLenum type,
2514 const GLvoid *pixels)
2515{
2516 // Zero sized uploads are valid but no-ops
2517 if (width == 0 || height == 0)
2518 {
2519 return;
2520 }
2521
Jamie Madillad9f24e2016-02-12 09:27:24 -05002522 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002523
2524 Box area(xoffset, yoffset, 0, width, height, 1);
2525 Texture *texture =
2526 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002527 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002528 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002529}
2530
2531void Context::texSubImage3D(GLenum target,
2532 GLint level,
2533 GLint xoffset,
2534 GLint yoffset,
2535 GLint zoffset,
2536 GLsizei width,
2537 GLsizei height,
2538 GLsizei depth,
2539 GLenum format,
2540 GLenum type,
2541 const GLvoid *pixels)
2542{
2543 // Zero sized uploads are valid but no-ops
2544 if (width == 0 || height == 0 || depth == 0)
2545 {
2546 return;
2547 }
2548
Jamie Madillad9f24e2016-02-12 09:27:24 -05002549 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002550
2551 Box area(xoffset, yoffset, zoffset, width, height, depth);
2552 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002553 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002554 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002555}
2556
2557void Context::compressedTexImage2D(GLenum target,
2558 GLint level,
2559 GLenum internalformat,
2560 GLsizei width,
2561 GLsizei height,
2562 GLint border,
2563 GLsizei imageSize,
2564 const GLvoid *data)
2565{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002566 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002567
2568 Extents size(width, height, 1);
2569 Texture *texture =
2570 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002571 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2572 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002573 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002574}
2575
2576void Context::compressedTexImage3D(GLenum target,
2577 GLint level,
2578 GLenum internalformat,
2579 GLsizei width,
2580 GLsizei height,
2581 GLsizei depth,
2582 GLint border,
2583 GLsizei imageSize,
2584 const GLvoid *data)
2585{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002586 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002587
2588 Extents size(width, height, depth);
2589 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002590 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2591 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002592 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002593}
2594
2595void Context::compressedTexSubImage2D(GLenum target,
2596 GLint level,
2597 GLint xoffset,
2598 GLint yoffset,
2599 GLsizei width,
2600 GLsizei height,
2601 GLenum format,
2602 GLsizei imageSize,
2603 const GLvoid *data)
2604{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002605 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002606
2607 Box area(xoffset, yoffset, 0, width, height, 1);
2608 Texture *texture =
2609 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002610 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2611 format, imageSize,
2612 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002613}
2614
2615void Context::compressedTexSubImage3D(GLenum target,
2616 GLint level,
2617 GLint xoffset,
2618 GLint yoffset,
2619 GLint zoffset,
2620 GLsizei width,
2621 GLsizei height,
2622 GLsizei depth,
2623 GLenum format,
2624 GLsizei imageSize,
2625 const GLvoid *data)
2626{
2627 // Zero sized uploads are valid but no-ops
2628 if (width == 0 || height == 0)
2629 {
2630 return;
2631 }
2632
Jamie Madillad9f24e2016-02-12 09:27:24 -05002633 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002634
2635 Box area(xoffset, yoffset, zoffset, width, height, depth);
2636 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002637 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2638 format, imageSize,
2639 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002640}
2641
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002642void Context::generateMipmap(GLenum target)
2643{
2644 Texture *texture = getTargetTexture(target);
2645 handleError(texture->generateMipmap());
2646}
2647
Olli Etuaho4f667482016-03-30 15:56:35 +03002648void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2649{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002650 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002651 ASSERT(buffer);
2652
2653 if (!buffer->isMapped())
2654 {
2655 *params = nullptr;
2656 }
2657 else
2658 {
2659 *params = buffer->getMapPointer();
2660 }
2661}
2662
2663GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2664{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002665 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002666 ASSERT(buffer);
2667
2668 Error error = buffer->map(access);
2669 if (error.isError())
2670 {
Jamie Madill437fa652016-05-03 15:13:24 -04002671 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002672 return nullptr;
2673 }
2674
2675 return buffer->getMapPointer();
2676}
2677
2678GLboolean Context::unmapBuffer(GLenum target)
2679{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002680 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002681 ASSERT(buffer);
2682
2683 GLboolean result;
2684 Error error = buffer->unmap(&result);
2685 if (error.isError())
2686 {
Jamie Madill437fa652016-05-03 15:13:24 -04002687 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002688 return GL_FALSE;
2689 }
2690
2691 return result;
2692}
2693
2694GLvoid *Context::mapBufferRange(GLenum target,
2695 GLintptr offset,
2696 GLsizeiptr length,
2697 GLbitfield access)
2698{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002699 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002700 ASSERT(buffer);
2701
2702 Error error = buffer->mapRange(offset, length, access);
2703 if (error.isError())
2704 {
Jamie Madill437fa652016-05-03 15:13:24 -04002705 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002706 return nullptr;
2707 }
2708
2709 return buffer->getMapPointer();
2710}
2711
2712void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2713{
2714 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2715}
2716
Jamie Madillad9f24e2016-02-12 09:27:24 -05002717void Context::syncStateForReadPixels()
2718{
2719 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2720}
2721
2722void Context::syncStateForTexImage()
2723{
2724 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2725}
2726
2727void Context::syncStateForClear()
2728{
2729 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2730}
2731
2732void Context::syncStateForBlit()
2733{
2734 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2735}
2736
Jamie Madillc20ab272016-06-09 07:20:46 -07002737void Context::activeTexture(GLenum texture)
2738{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002739 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002740}
2741
2742void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2743{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002744 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07002745}
2746
2747void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2748{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002749 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002750}
2751
2752void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2753{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002754 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002755}
2756
2757void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2758{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002759 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002760}
2761
2762void Context::clearDepthf(GLclampf depth)
2763{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002764 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07002765}
2766
2767void Context::clearStencil(GLint s)
2768{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002769 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07002770}
2771
2772void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2773{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002774 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002775}
2776
2777void Context::cullFace(GLenum mode)
2778{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002779 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002780}
2781
2782void Context::depthFunc(GLenum func)
2783{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002784 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07002785}
2786
2787void Context::depthMask(GLboolean flag)
2788{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002789 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002790}
2791
2792void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2793{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002794 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07002795}
2796
2797void Context::disable(GLenum cap)
2798{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002799 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002800}
2801
2802void Context::disableVertexAttribArray(GLuint index)
2803{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002805}
2806
2807void Context::enable(GLenum cap)
2808{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002809 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002810}
2811
2812void Context::enableVertexAttribArray(GLuint index)
2813{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002814 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002815}
2816
2817void Context::frontFace(GLenum mode)
2818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002820}
2821
2822void Context::hint(GLenum target, GLenum mode)
2823{
2824 switch (target)
2825 {
2826 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002828 break;
2829
2830 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002831 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002832 break;
2833
2834 default:
2835 UNREACHABLE();
2836 return;
2837 }
2838}
2839
2840void Context::lineWidth(GLfloat width)
2841{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002842 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07002843}
2844
2845void Context::pixelStorei(GLenum pname, GLint param)
2846{
2847 switch (pname)
2848 {
2849 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002851 break;
2852
2853 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002854 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002855 break;
2856
2857 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002858 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002859 break;
2860
2861 case GL_UNPACK_ROW_LENGTH:
2862 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002864 break;
2865
2866 case GL_UNPACK_IMAGE_HEIGHT:
2867 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002868 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002869 break;
2870
2871 case GL_UNPACK_SKIP_IMAGES:
2872 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002873 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002874 break;
2875
2876 case GL_UNPACK_SKIP_ROWS:
2877 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002878 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002879 break;
2880
2881 case GL_UNPACK_SKIP_PIXELS:
2882 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002883 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002884 break;
2885
2886 case GL_PACK_ROW_LENGTH:
2887 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002888 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002889 break;
2890
2891 case GL_PACK_SKIP_ROWS:
2892 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002893 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002894 break;
2895
2896 case GL_PACK_SKIP_PIXELS:
2897 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002898 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002899 break;
2900
2901 default:
2902 UNREACHABLE();
2903 return;
2904 }
2905}
2906
2907void Context::polygonOffset(GLfloat factor, GLfloat units)
2908{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002909 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07002910}
2911
2912void Context::sampleCoverage(GLclampf value, GLboolean invert)
2913{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002914 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002915}
2916
2917void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2918{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002919 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002920}
2921
2922void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2923{
2924 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2925 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002926 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002927 }
2928
2929 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2930 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002931 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002932 }
2933}
2934
2935void Context::stencilMaskSeparate(GLenum face, GLuint mask)
2936{
2937 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2938 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002939 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002940 }
2941
2942 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2943 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002944 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002945 }
2946}
2947
2948void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
2949{
2950 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2951 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002952 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002953 }
2954
2955 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2956 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002957 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002958 }
2959}
2960
2961void Context::vertexAttrib1f(GLuint index, GLfloat x)
2962{
2963 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002964 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002965}
2966
2967void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
2968{
2969 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002970 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002971}
2972
2973void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
2974{
2975 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002976 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002977}
2978
2979void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
2980{
2981 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002982 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002983}
2984
2985void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
2986{
2987 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002988 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002989}
2990
2991void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
2992{
2993 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002994 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002995}
2996
2997void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2998{
2999 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003000 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003001}
3002
3003void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
3004{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003005 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07003006}
3007
3008void Context::vertexAttribPointer(GLuint index,
3009 GLint size,
3010 GLenum type,
3011 GLboolean normalized,
3012 GLsizei stride,
3013 const GLvoid *ptr)
3014{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003015 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3016 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07003017}
3018
3019void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
3020{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003021 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07003022}
3023
3024void Context::vertexAttribIPointer(GLuint index,
3025 GLint size,
3026 GLenum type,
3027 GLsizei stride,
3028 const GLvoid *pointer)
3029{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003030 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3031 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003032}
3033
3034void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3035{
3036 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003037 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003038}
3039
3040void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3041{
3042 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003043 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003044}
3045
3046void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3047{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003048 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003049}
3050
3051void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3052{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003053 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003054}
3055
3056void Context::debugMessageControl(GLenum source,
3057 GLenum type,
3058 GLenum severity,
3059 GLsizei count,
3060 const GLuint *ids,
3061 GLboolean enabled)
3062{
3063 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003064 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3065 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003066}
3067
3068void Context::debugMessageInsert(GLenum source,
3069 GLenum type,
3070 GLuint id,
3071 GLenum severity,
3072 GLsizei length,
3073 const GLchar *buf)
3074{
3075 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003076 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003077}
3078
3079void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3080{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003081 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003082}
3083
3084GLuint Context::getDebugMessageLog(GLuint count,
3085 GLsizei bufSize,
3086 GLenum *sources,
3087 GLenum *types,
3088 GLuint *ids,
3089 GLenum *severities,
3090 GLsizei *lengths,
3091 GLchar *messageLog)
3092{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003093 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3094 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003095}
3096
3097void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3098{
3099 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003100 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003101}
3102
3103void Context::popDebugGroup()
3104{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003105 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003106}
3107
Jamie Madillc29968b2016-01-20 11:17:23 -05003108} // namespace gl