blob: 9b3ecc73f1aa6ca0fc5de603e8065737d229b601 [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}
1543void Context::coverStrokePathInstanced(GLsizei numPaths,
1544 GLenum pathNameType,
1545 const void *paths,
1546 GLuint pathBase,
1547 GLenum coverMode,
1548 GLenum transformType,
1549 const GLfloat *transformValues)
1550{
1551 const auto &pathObjects =
1552 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1553
1554 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1555 syncRendererState();
1556
1557 mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType,
1558 transformValues);
1559}
1560void Context::stencilFillPathInstanced(GLsizei numPaths,
1561 GLenum pathNameType,
1562 const void *paths,
1563 GLuint pathBase,
1564 GLenum fillMode,
1565 GLuint mask,
1566 GLenum transformType,
1567 const GLfloat *transformValues)
1568{
1569 const auto &pathObjects =
1570 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1571
1572 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1573 syncRendererState();
1574
1575 mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType,
1576 transformValues);
1577}
1578void Context::stencilStrokePathInstanced(GLsizei numPaths,
1579 GLenum pathNameType,
1580 const void *paths,
1581 GLuint pathBase,
1582 GLint reference,
1583 GLuint mask,
1584 GLenum transformType,
1585 const GLfloat *transformValues)
1586{
1587 const auto &pathObjects =
1588 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1589
1590 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1591 syncRendererState();
1592
1593 mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType,
1594 transformValues);
1595}
1596void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths,
1597 GLenum pathNameType,
1598 const void *paths,
1599 GLuint pathBase,
1600 GLenum fillMode,
1601 GLuint mask,
1602 GLenum coverMode,
1603 GLenum transformType,
1604 const GLfloat *transformValues)
1605{
1606 const auto &pathObjects =
1607 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1608
1609 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1610 syncRendererState();
1611
1612 mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask,
1613 transformType, transformValues);
1614}
1615void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
1616 GLenum pathNameType,
1617 const void *paths,
1618 GLuint pathBase,
1619 GLint reference,
1620 GLuint mask,
1621 GLenum coverMode,
1622 GLenum transformType,
1623 const GLfloat *transformValues)
1624{
1625 const auto &pathObjects =
1626 GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase);
1627
1628 // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering?
1629 syncRendererState();
1630
1631 mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask,
1632 transformType, transformValues);
1633}
1634
Jamie Madill437fa652016-05-03 15:13:24 -04001635void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636{
Geoff Langda5777c2014-07-11 09:52:58 -04001637 if (error.isError())
1638 {
1639 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001640
1641 if (!error.getMessage().empty())
1642 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001643 auto *debug = &mGLState.getDebug();
1644 debug->insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1645 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
Geoff Lang70d0f492015-12-10 17:45:46 -05001646 }
Geoff Langda5777c2014-07-11 09:52:58 -04001647 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001648}
1649
1650// Get one of the recorded errors and clear its flag, if any.
1651// [OpenGL ES 2.0.24] section 2.5 page 13.
1652GLenum Context::getError()
1653{
Geoff Langda5777c2014-07-11 09:52:58 -04001654 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001655 {
Geoff Langda5777c2014-07-11 09:52:58 -04001656 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001657 }
Geoff Langda5777c2014-07-11 09:52:58 -04001658 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659 {
Geoff Langda5777c2014-07-11 09:52:58 -04001660 GLenum error = *mErrors.begin();
1661 mErrors.erase(mErrors.begin());
1662 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001663 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001664}
1665
1666GLenum Context::getResetStatus()
1667{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001668 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001669 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001670 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001671 // mResetStatus will be set by the markContextLost callback
1672 // in the case a notification is sent
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001673 if (mImplementation->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001674 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001675 mImplementation->notifyDeviceLost();
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001676 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001677 }
1678
1679 GLenum status = mResetStatus;
1680
1681 if (mResetStatus != GL_NO_ERROR)
1682 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001683 ASSERT(mContextLost);
1684
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001685 if (mImplementation->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001686 {
1687 mResetStatus = GL_NO_ERROR;
1688 }
1689 }
Jamie Madill893ab082014-05-16 16:56:10 -04001690
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001691 return status;
1692}
1693
1694bool Context::isResetNotificationEnabled()
1695{
1696 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1697}
1698
Corentin Walleze3b10e82015-05-20 11:06:25 -04001699const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001700{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001701 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001702}
1703
1704EGLenum Context::getClientType() const
1705{
1706 return mClientType;
1707}
1708
1709EGLenum Context::getRenderBuffer() const
1710{
Corentin Wallez37c39792015-08-20 14:19:46 -04001711 auto framebufferIt = mFramebufferMap.find(0);
1712 if (framebufferIt != mFramebufferMap.end())
1713 {
1714 const Framebuffer *framebuffer = framebufferIt->second;
1715 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1716
1717 ASSERT(backAttachment != nullptr);
1718 return backAttachment->getSurface()->getRenderBuffer();
1719 }
1720 else
1721 {
1722 return EGL_NONE;
1723 }
Régis Fénéon83107972015-02-05 12:57:44 +01001724}
1725
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001726VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001727{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001728 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001729 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1730 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001731 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001732 vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1733
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001734 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001735 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001736
1737 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001738}
1739
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001740TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001741{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001742 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001743 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1744 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001745 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001746 transformFeedback =
1747 new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps);
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001748 transformFeedback->addRef();
1749 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001750 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001751
1752 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001753}
1754
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001755Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1756{
1757 // Can be called from Bind without a prior call to Gen.
1758 auto framebufferIt = mFramebufferMap.find(framebuffer);
1759 bool neverCreated = framebufferIt == mFramebufferMap.end();
1760 if (neverCreated || framebufferIt->second == nullptr)
1761 {
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001762 Framebuffer *newFBO = new Framebuffer(mCaps, mImplementation.get(), framebuffer);
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001763 if (neverCreated)
1764 {
1765 mFramebufferHandleAllocator.reserve(framebuffer);
1766 mFramebufferMap[framebuffer] = newFBO;
1767 return newFBO;
1768 }
1769
1770 framebufferIt->second = newFBO;
1771 }
1772
1773 return framebufferIt->second;
1774}
1775
Geoff Lang36167ab2015-12-07 10:27:14 -05001776bool Context::isVertexArrayGenerated(GLuint vertexArray)
1777{
1778 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1779}
1780
1781bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1782{
1783 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1784}
1785
Shannon Woods53a94a82014-06-24 15:20:36 -04001786void Context::detachTexture(GLuint texture)
1787{
1788 // Simple pass-through to State's detachTexture method, as textures do not require
1789 // allocation map management either here or in the resource manager at detach time.
1790 // Zero textures are held by the Context, and we don't attempt to request them from
1791 // the State.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001792 mGLState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001793}
1794
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001795void Context::detachBuffer(GLuint buffer)
1796{
Yuly Novikov5807a532015-12-03 13:01:22 -05001797 // Simple pass-through to State's detachBuffer method, since
1798 // only buffer attachments to container objects that are bound to the current context
1799 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001800
Yuly Novikov5807a532015-12-03 13:01:22 -05001801 // [OpenGL ES 3.2] section 5.1.2 page 45:
1802 // Attachments to unbound container objects, such as
1803 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1804 // are not affected and continue to act as references on the deleted object
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001805 mGLState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001806}
1807
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001808void Context::detachFramebuffer(GLuint framebuffer)
1809{
Shannon Woods53a94a82014-06-24 15:20:36 -04001810 // Framebuffer detachment is handled by Context, because 0 is a valid
1811 // Framebuffer object, and a pointer to it must be passed from Context
1812 // to State at binding time.
1813
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001814 // [OpenGL ES 2.0.24] section 4.4 page 107:
1815 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1816 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1817
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001818 if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001819 {
1820 bindReadFramebuffer(0);
1821 }
1822
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001823 if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001824 {
1825 bindDrawFramebuffer(0);
1826 }
1827}
1828
1829void Context::detachRenderbuffer(GLuint renderbuffer)
1830{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001831 mGLState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832}
1833
Jamie Madill57a89722013-07-02 11:57:03 -04001834void Context::detachVertexArray(GLuint vertexArray)
1835{
Jamie Madill77a72f62015-04-14 11:18:32 -04001836 // Vertex array detachment is handled by Context, because 0 is a valid
1837 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001838 // binding time.
1839
Jamie Madill57a89722013-07-02 11:57:03 -04001840 // [OpenGL ES 3.0.2] section 2.10 page 43:
1841 // If a vertex array object that is currently bound is deleted, the binding
1842 // for that object reverts to zero and the default vertex array becomes current.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001843 if (mGLState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001844 {
1845 bindVertexArray(0);
1846 }
1847}
1848
Geoff Langc8058452014-02-03 12:04:11 -05001849void Context::detachTransformFeedback(GLuint transformFeedback)
1850{
Corentin Walleza2257da2016-04-19 16:43:12 -04001851 // Transform feedback detachment is handled by Context, because 0 is a valid
1852 // transform feedback, and a pointer to it must be passed from Context to State at
1853 // binding time.
1854
1855 // The OpenGL specification doesn't mention what should happen when the currently bound
1856 // transform feedback object is deleted. Since it is a container object, we treat it like
1857 // VAOs and FBOs and set the current bound transform feedback back to 0.
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001858 if (mGLState.removeTransformFeedbackBinding(transformFeedback))
Corentin Walleza2257da2016-04-19 16:43:12 -04001859 {
1860 bindTransformFeedback(0);
1861 }
Geoff Langc8058452014-02-03 12:04:11 -05001862}
1863
Jamie Madilldc356042013-07-19 16:36:57 -04001864void Context::detachSampler(GLuint sampler)
1865{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001866 mGLState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001867}
1868
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001869void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1870{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001871 mGLState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001872}
1873
Jamie Madille29d1672013-07-19 16:36:57 -04001874void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1875{
Jamie Madill901b3792016-05-26 09:20:40 -04001876 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001877
1878 Sampler *samplerObject = getSampler(sampler);
1879 ASSERT(samplerObject);
1880
Geoff Lang69cce582015-09-17 13:20:36 -04001881 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001882 switch (pname)
1883 {
Geoff Lang69cce582015-09-17 13:20:36 -04001884 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1885 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1886 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1887 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1888 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1889 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1890 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1891 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1892 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1893 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1894 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001895 }
Geoff Lang69cce582015-09-17 13:20:36 -04001896 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001897}
1898
1899void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1900{
Jamie Madill901b3792016-05-26 09:20:40 -04001901 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madille29d1672013-07-19 16:36:57 -04001902
1903 Sampler *samplerObject = getSampler(sampler);
1904 ASSERT(samplerObject);
1905
Geoff Lang69cce582015-09-17 13:20:36 -04001906 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001907 switch (pname)
1908 {
Geoff Lang69cce582015-09-17 13:20:36 -04001909 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1910 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1911 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1912 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1913 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1914 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1915 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1916 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1917 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1918 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1919 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001920 }
Geoff Lang69cce582015-09-17 13:20:36 -04001921 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001922}
1923
Jamie Madill9675b802013-07-19 16:36:59 -04001924GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1925{
Jamie Madill901b3792016-05-26 09:20:40 -04001926 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001927
1928 Sampler *samplerObject = getSampler(sampler);
1929 ASSERT(samplerObject);
1930
Geoff Lang69cce582015-09-17 13:20:36 -04001931 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001932 switch (pname)
1933 {
Geoff Lang69cce582015-09-17 13:20:36 -04001934 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1935 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1936 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1937 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1938 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1939 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001940 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1941 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001942 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1943 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1944 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001945 }
Geoff Lang69cce582015-09-17 13:20:36 -04001946 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001947}
1948
1949GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1950{
Jamie Madill901b3792016-05-26 09:20:40 -04001951 mResourceManager->checkSamplerAllocation(mImplementation.get(), sampler);
Jamie Madill9675b802013-07-19 16:36:59 -04001952
1953 Sampler *samplerObject = getSampler(sampler);
1954 ASSERT(samplerObject);
1955
Geoff Lang69cce582015-09-17 13:20:36 -04001956 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001957 switch (pname)
1958 {
Geoff Lang69cce582015-09-17 13:20:36 -04001959 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1960 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1961 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1962 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1963 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1964 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1965 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1966 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1967 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1968 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1969 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001970 }
Geoff Lang69cce582015-09-17 13:20:36 -04001971 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001972}
1973
Olli Etuahof0fee072016-03-30 15:11:58 +03001974void Context::programParameteri(GLuint program, GLenum pname, GLint value)
1975{
1976 gl::Program *programObject = getProgram(program);
1977 ASSERT(programObject != nullptr);
1978
1979 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
1980 programObject->setBinaryRetrievableHint(value != GL_FALSE);
1981}
1982
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001983void Context::initRendererString()
1984{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001985 std::ostringstream rendererString;
1986 rendererString << "ANGLE (";
Jamie Madill53ea9cc2016-05-17 10:12:52 -04001987 rendererString << mImplementation->getRendererDescription();
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001988 rendererString << ")";
1989
Geoff Langcec35902014-04-16 10:52:36 -04001990 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001991}
1992
Geoff Langc0b9ef42014-07-02 10:02:37 -04001993const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001994{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001995 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001996}
1997
Geoff Langcec35902014-04-16 10:52:36 -04001998void Context::initExtensionStrings()
1999{
Geoff Lang493daf52014-07-03 13:38:44 -04002000 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002001
Geoff Langc0b9ef42014-07-02 10:02:37 -04002002 std::ostringstream combinedStringStream;
2003 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2004 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002005}
2006
Geoff Langc0b9ef42014-07-02 10:02:37 -04002007const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002008{
2009 return mExtensionString;
2010}
2011
Geoff Langc0b9ef42014-07-02 10:02:37 -04002012const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002013{
2014 return mExtensionStrings[idx];
2015}
2016
2017size_t Context::getExtensionStringCount() const
2018{
2019 return mExtensionStrings.size();
2020}
2021
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002022void Context::beginTransformFeedback(GLenum primitiveMode)
2023{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002024 TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback();
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002025 ASSERT(transformFeedback != nullptr);
2026 ASSERT(!transformFeedback->isPaused());
2027
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002028 transformFeedback->begin(primitiveMode, mGLState.getProgram());
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002029}
2030
2031bool Context::hasActiveTransformFeedback(GLuint program) const
2032{
2033 for (auto pair : mTransformFeedbackMap)
2034 {
2035 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2036 {
2037 return true;
2038 }
2039 }
2040 return false;
2041}
2042
Jamie Madill00ed7a12016-05-19 13:13:38 -04002043void Context::initCaps()
Geoff Lang493daf52014-07-03 13:38:44 -04002044{
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002045 mCaps = mImplementation->getNativeCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002046
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002047 mExtensions = mImplementation->getNativeExtensions();
Geoff Lang493daf52014-07-03 13:38:44 -04002048
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002049 mLimitations = mImplementation->getNativeLimitations();
Austin Kinross02df7962015-07-01 10:03:42 -07002050
Jamie Madill00ed7a12016-05-19 13:13:38 -04002051 if (mClientVersion < 3)
Geoff Lang493daf52014-07-03 13:38:44 -04002052 {
2053 // Disable ES3+ extensions
2054 mExtensions.colorBufferFloat = false;
Geoff Langb66a9092016-05-16 15:59:14 -04002055 mExtensions.eglImageExternalEssl3 = false;
Vincent Lang25ab4512016-05-13 18:13:59 +02002056 mExtensions.textureNorm16 = false;
Geoff Lang493daf52014-07-03 13:38:44 -04002057 }
2058
Jamie Madill00ed7a12016-05-19 13:13:38 -04002059 if (mClientVersion > 2)
Geoff Lang493daf52014-07-03 13:38:44 -04002060 {
2061 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2062 //mExtensions.sRGB = false;
2063 }
2064
Jamie Madill00ed7a12016-05-19 13:13:38 -04002065 // Some extensions are always available because they are implemented in the GL layer.
2066 mExtensions.bindUniformLocation = true;
2067 mExtensions.vertexArrayObject = true;
2068
2069 // Enable the no error extension if the context was created with the flag.
2070 mExtensions.noError = mSkipValidation;
2071
Geoff Lang70d0f492015-12-10 17:45:46 -05002072 // Explicitly enable GL_KHR_debug
2073 mExtensions.debug = true;
2074 mExtensions.maxDebugMessageLength = 1024;
2075 mExtensions.maxDebugLoggedMessages = 1024;
2076 mExtensions.maxDebugGroupStackDepth = 1024;
2077 mExtensions.maxLabelLength = 1024;
2078
Geoff Lang301d1612014-07-09 10:34:37 -04002079 // Apply implementation limits
2080 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002081 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2082 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2083
2084 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002085
Geoff Lang900013c2014-07-07 11:32:19 -04002086 mCaps.compressedTextureFormats.clear();
2087
Jamie Madill53ea9cc2016-05-17 10:12:52 -04002088 const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps();
Geoff Lang493daf52014-07-03 13:38:44 -04002089 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2090 {
2091 GLenum format = i->first;
2092 TextureCaps formatCaps = i->second;
2093
Geoff Lang5d601382014-07-22 15:14:06 -04002094 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002095
Geoff Lang0d8b7242015-09-09 14:56:53 -04002096 // Update the format caps based on the client version and extensions.
2097 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2098 // ES3.
2099 formatCaps.texturable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002100 formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002101 formatCaps.renderable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002102 formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions);
Geoff Lang0d8b7242015-09-09 14:56:53 -04002103 formatCaps.filterable =
Jamie Madill00ed7a12016-05-19 13:13:38 -04002104 formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002105
2106 // OpenGL ES does not support multisampling with integer formats
2107 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002108 {
Geoff Langd87878e2014-09-19 15:42:59 -04002109 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002110 }
Geoff Langd87878e2014-09-19 15:42:59 -04002111
2112 if (formatCaps.texturable && formatInfo.compressed)
2113 {
2114 mCaps.compressedTextureFormats.push_back(format);
2115 }
2116
2117 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002118 }
2119}
2120
Jamie Madill1b94d432015-08-07 13:23:23 -04002121void Context::syncRendererState()
2122{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002123 const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
2124 mImplementation->syncState(mGLState, dirtyBits);
2125 mGLState.clearDirtyBits();
2126 mGLState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002127}
2128
Jamie Madillad9f24e2016-02-12 09:27:24 -05002129void Context::syncRendererState(const State::DirtyBits &bitMask,
2130 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002131{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002132 const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
2133 mImplementation->syncState(mGLState, dirtyBits);
2134 mGLState.clearDirtyBits(dirtyBits);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002135
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002136 mGLState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002137}
Jamie Madillc29968b2016-01-20 11:17:23 -05002138
2139void Context::blitFramebuffer(GLint srcX0,
2140 GLint srcY0,
2141 GLint srcX1,
2142 GLint srcY1,
2143 GLint dstX0,
2144 GLint dstY0,
2145 GLint dstX1,
2146 GLint dstY1,
2147 GLbitfield mask,
2148 GLenum filter)
2149{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002150 Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002151 ASSERT(drawFramebuffer);
2152
2153 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2154 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2155
Jamie Madillad9f24e2016-02-12 09:27:24 -05002156 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002157
Jamie Madill8415b5f2016-04-26 13:41:39 -04002158 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002159}
Jamie Madillc29968b2016-01-20 11:17:23 -05002160
2161void Context::clear(GLbitfield mask)
2162{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002163 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002164 handleError(mGLState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002165}
2166
2167void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2168{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002169 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002170 handleError(mGLState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2171 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002172}
2173
2174void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2175{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002176 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002177 handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2178 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002179}
2180
2181void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2182{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002183 syncStateForClear();
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002184 handleError(mGLState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2185 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002186}
2187
2188void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2189{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002190 Framebuffer *framebufferObject = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002191 ASSERT(framebufferObject);
2192
2193 // If a buffer is not present, the clear has no effect
2194 if (framebufferObject->getDepthbuffer() == nullptr &&
2195 framebufferObject->getStencilbuffer() == nullptr)
2196 {
2197 return;
2198 }
2199
Jamie Madillad9f24e2016-02-12 09:27:24 -05002200 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002201 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2202 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002203}
2204
2205void Context::readPixels(GLint x,
2206 GLint y,
2207 GLsizei width,
2208 GLsizei height,
2209 GLenum format,
2210 GLenum type,
2211 GLvoid *pixels)
2212{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002213 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002214
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002215 Framebuffer *framebufferObject = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002216 ASSERT(framebufferObject);
2217
2218 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002219 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002220}
2221
2222void Context::copyTexImage2D(GLenum target,
2223 GLint level,
2224 GLenum internalformat,
2225 GLint x,
2226 GLint y,
2227 GLsizei width,
2228 GLsizei height,
2229 GLint border)
2230{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002231 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002232 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002233
Jamie Madillc29968b2016-01-20 11:17:23 -05002234 Rectangle sourceArea(x, y, width, height);
2235
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002236 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002237 Texture *texture =
2238 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002239 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002240}
2241
2242void Context::copyTexSubImage2D(GLenum target,
2243 GLint level,
2244 GLint xoffset,
2245 GLint yoffset,
2246 GLint x,
2247 GLint y,
2248 GLsizei width,
2249 GLsizei height)
2250{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002251 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002252 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002253
Jamie Madillc29968b2016-01-20 11:17:23 -05002254 Offset destOffset(xoffset, yoffset, 0);
2255 Rectangle sourceArea(x, y, width, height);
2256
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002257 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002258 Texture *texture =
2259 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002260 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002261}
2262
2263void Context::copyTexSubImage3D(GLenum target,
2264 GLint level,
2265 GLint xoffset,
2266 GLint yoffset,
2267 GLint zoffset,
2268 GLint x,
2269 GLint y,
2270 GLsizei width,
2271 GLsizei height)
2272{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002273 // Only sync the read FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002274 mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002275
Jamie Madillc29968b2016-01-20 11:17:23 -05002276 Offset destOffset(xoffset, yoffset, zoffset);
2277 Rectangle sourceArea(x, y, width, height);
2278
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002279 const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002280 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002281 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002282}
2283
2284void Context::framebufferTexture2D(GLenum target,
2285 GLenum attachment,
2286 GLenum textarget,
2287 GLuint texture,
2288 GLint level)
2289{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002290 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002291 ASSERT(framebuffer);
2292
2293 if (texture != 0)
2294 {
2295 Texture *textureObj = getTexture(texture);
2296
2297 ImageIndex index = ImageIndex::MakeInvalid();
2298
2299 if (textarget == GL_TEXTURE_2D)
2300 {
2301 index = ImageIndex::Make2D(level);
2302 }
2303 else
2304 {
2305 ASSERT(IsCubeMapTextureTarget(textarget));
2306 index = ImageIndex::MakeCube(textarget, level);
2307 }
2308
2309 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2310 }
2311 else
2312 {
2313 framebuffer->resetAttachment(attachment);
2314 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002315
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002316 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002317}
2318
2319void Context::framebufferRenderbuffer(GLenum target,
2320 GLenum attachment,
2321 GLenum renderbuffertarget,
2322 GLuint renderbuffer)
2323{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002324 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002325 ASSERT(framebuffer);
2326
2327 if (renderbuffer != 0)
2328 {
2329 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2330 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2331 renderbufferObject);
2332 }
2333 else
2334 {
2335 framebuffer->resetAttachment(attachment);
2336 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002337
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002338 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002339}
2340
2341void Context::framebufferTextureLayer(GLenum target,
2342 GLenum attachment,
2343 GLuint texture,
2344 GLint level,
2345 GLint layer)
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 (texture != 0)
2351 {
2352 Texture *textureObject = getTexture(texture);
2353
2354 ImageIndex index = ImageIndex::MakeInvalid();
2355
2356 if (textureObject->getTarget() == GL_TEXTURE_3D)
2357 {
2358 index = ImageIndex::Make3D(level, layer);
2359 }
2360 else
2361 {
2362 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2363 index = ImageIndex::Make2DArray(level, layer);
2364 }
2365
2366 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2367 }
2368 else
2369 {
2370 framebuffer->resetAttachment(attachment);
2371 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002372
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002373 mGLState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002374}
2375
2376void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2377{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002378 Framebuffer *framebuffer = mGLState.getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002379 ASSERT(framebuffer);
2380 framebuffer->setDrawBuffers(n, bufs);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002381 mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002382}
2383
2384void Context::readBuffer(GLenum mode)
2385{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002386 Framebuffer *readFBO = mGLState.getReadFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002387 readFBO->setReadBuffer(mode);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002388 mGLState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002389}
2390
2391void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2392{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002393 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002394 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002395
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002396 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002397 ASSERT(framebuffer);
2398
2399 // The specification isn't clear what should be done when the framebuffer isn't complete.
2400 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002401 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002402}
2403
2404void Context::invalidateFramebuffer(GLenum target,
2405 GLsizei numAttachments,
2406 const GLenum *attachments)
2407{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002408 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002409 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002410
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002411 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002412 ASSERT(framebuffer);
2413
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002414 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002415 {
Jamie Madill437fa652016-05-03 15:13:24 -04002416 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002417 }
Jamie Madill437fa652016-05-03 15:13:24 -04002418
2419 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002420}
2421
2422void Context::invalidateSubFramebuffer(GLenum target,
2423 GLsizei numAttachments,
2424 const GLenum *attachments,
2425 GLint x,
2426 GLint y,
2427 GLsizei width,
2428 GLsizei height)
2429{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002430 // Only sync the FBO
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002431 mGLState.syncDirtyObject(target);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002432
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002433 Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 ASSERT(framebuffer);
2435
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002436 if (framebuffer->checkStatus(mState) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002437 {
Jamie Madill437fa652016-05-03 15:13:24 -04002438 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002439 }
Jamie Madill437fa652016-05-03 15:13:24 -04002440
2441 Rectangle area(x, y, width, height);
2442 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002443}
2444
Jamie Madill73a84962016-02-12 09:27:23 -05002445void Context::texImage2D(GLenum target,
2446 GLint level,
2447 GLint internalformat,
2448 GLsizei width,
2449 GLsizei height,
2450 GLint border,
2451 GLenum format,
2452 GLenum type,
2453 const GLvoid *pixels)
2454{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002455 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002456
2457 Extents size(width, height, 1);
2458 Texture *texture =
2459 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002460 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002461 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002462}
2463
2464void Context::texImage3D(GLenum target,
2465 GLint level,
2466 GLint internalformat,
2467 GLsizei width,
2468 GLsizei height,
2469 GLsizei depth,
2470 GLint border,
2471 GLenum format,
2472 GLenum type,
2473 const GLvoid *pixels)
2474{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002475 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002476
2477 Extents size(width, height, depth);
2478 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002479 handleError(texture->setImage(mGLState.getUnpackState(), target, level, internalformat, size,
Jamie Madill437fa652016-05-03 15:13:24 -04002480 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002481}
2482
2483void Context::texSubImage2D(GLenum target,
2484 GLint level,
2485 GLint xoffset,
2486 GLint yoffset,
2487 GLsizei width,
2488 GLsizei height,
2489 GLenum format,
2490 GLenum type,
2491 const GLvoid *pixels)
2492{
2493 // Zero sized uploads are valid but no-ops
2494 if (width == 0 || height == 0)
2495 {
2496 return;
2497 }
2498
Jamie Madillad9f24e2016-02-12 09:27:24 -05002499 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002500
2501 Box area(xoffset, yoffset, 0, width, height, 1);
2502 Texture *texture =
2503 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002504 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002505 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002506}
2507
2508void Context::texSubImage3D(GLenum target,
2509 GLint level,
2510 GLint xoffset,
2511 GLint yoffset,
2512 GLint zoffset,
2513 GLsizei width,
2514 GLsizei height,
2515 GLsizei depth,
2516 GLenum format,
2517 GLenum type,
2518 const GLvoid *pixels)
2519{
2520 // Zero sized uploads are valid but no-ops
2521 if (width == 0 || height == 0 || depth == 0)
2522 {
2523 return;
2524 }
2525
Jamie Madillad9f24e2016-02-12 09:27:24 -05002526 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002527
2528 Box area(xoffset, yoffset, zoffset, width, height, depth);
2529 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002530 handleError(texture->setSubImage(mGLState.getUnpackState(), target, level, area, format, type,
Jamie Madill437fa652016-05-03 15:13:24 -04002531 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002532}
2533
2534void Context::compressedTexImage2D(GLenum target,
2535 GLint level,
2536 GLenum internalformat,
2537 GLsizei width,
2538 GLsizei height,
2539 GLint border,
2540 GLsizei imageSize,
2541 const GLvoid *data)
2542{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002543 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002544
2545 Extents size(width, height, 1);
2546 Texture *texture =
2547 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002548 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2549 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002550 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002551}
2552
2553void Context::compressedTexImage3D(GLenum target,
2554 GLint level,
2555 GLenum internalformat,
2556 GLsizei width,
2557 GLsizei height,
2558 GLsizei depth,
2559 GLint border,
2560 GLsizei imageSize,
2561 const GLvoid *data)
2562{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002563 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002564
2565 Extents size(width, height, depth);
2566 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002567 handleError(texture->setCompressedImage(mGLState.getUnpackState(), target, level,
2568 internalformat, size, imageSize,
Jamie Madill437fa652016-05-03 15:13:24 -04002569 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002570}
2571
2572void Context::compressedTexSubImage2D(GLenum target,
2573 GLint level,
2574 GLint xoffset,
2575 GLint yoffset,
2576 GLsizei width,
2577 GLsizei height,
2578 GLenum format,
2579 GLsizei imageSize,
2580 const GLvoid *data)
2581{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002582 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002583
2584 Box area(xoffset, yoffset, 0, width, height, 1);
2585 Texture *texture =
2586 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002587 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2588 format, imageSize,
2589 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002590}
2591
2592void Context::compressedTexSubImage3D(GLenum target,
2593 GLint level,
2594 GLint xoffset,
2595 GLint yoffset,
2596 GLint zoffset,
2597 GLsizei width,
2598 GLsizei height,
2599 GLsizei depth,
2600 GLenum format,
2601 GLsizei imageSize,
2602 const GLvoid *data)
2603{
2604 // Zero sized uploads are valid but no-ops
2605 if (width == 0 || height == 0)
2606 {
2607 return;
2608 }
2609
Jamie Madillad9f24e2016-02-12 09:27:24 -05002610 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002611
2612 Box area(xoffset, yoffset, zoffset, width, height, depth);
2613 Texture *texture = getTargetTexture(target);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002614 handleError(texture->setCompressedSubImage(mGLState.getUnpackState(), target, level, area,
2615 format, imageSize,
2616 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002617}
2618
Olli Etuaho0f2b1562016-05-13 16:15:35 +03002619void Context::generateMipmap(GLenum target)
2620{
2621 Texture *texture = getTargetTexture(target);
2622 handleError(texture->generateMipmap());
2623}
2624
Olli Etuaho4f667482016-03-30 15:56:35 +03002625void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2626{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002627 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002628 ASSERT(buffer);
2629
2630 if (!buffer->isMapped())
2631 {
2632 *params = nullptr;
2633 }
2634 else
2635 {
2636 *params = buffer->getMapPointer();
2637 }
2638}
2639
2640GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2641{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002642 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002643 ASSERT(buffer);
2644
2645 Error error = buffer->map(access);
2646 if (error.isError())
2647 {
Jamie Madill437fa652016-05-03 15:13:24 -04002648 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002649 return nullptr;
2650 }
2651
2652 return buffer->getMapPointer();
2653}
2654
2655GLboolean Context::unmapBuffer(GLenum target)
2656{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002657 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002658 ASSERT(buffer);
2659
2660 GLboolean result;
2661 Error error = buffer->unmap(&result);
2662 if (error.isError())
2663 {
Jamie Madill437fa652016-05-03 15:13:24 -04002664 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002665 return GL_FALSE;
2666 }
2667
2668 return result;
2669}
2670
2671GLvoid *Context::mapBufferRange(GLenum target,
2672 GLintptr offset,
2673 GLsizeiptr length,
2674 GLbitfield access)
2675{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002676 Buffer *buffer = mGLState.getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002677 ASSERT(buffer);
2678
2679 Error error = buffer->mapRange(offset, length, access);
2680 if (error.isError())
2681 {
Jamie Madill437fa652016-05-03 15:13:24 -04002682 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002683 return nullptr;
2684 }
2685
2686 return buffer->getMapPointer();
2687}
2688
2689void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2690{
2691 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2692}
2693
Jamie Madillad9f24e2016-02-12 09:27:24 -05002694void Context::syncStateForReadPixels()
2695{
2696 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2697}
2698
2699void Context::syncStateForTexImage()
2700{
2701 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2702}
2703
2704void Context::syncStateForClear()
2705{
2706 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2707}
2708
2709void Context::syncStateForBlit()
2710{
2711 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2712}
2713
Jamie Madillc20ab272016-06-09 07:20:46 -07002714void Context::activeTexture(GLenum texture)
2715{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002716 mGLState.setActiveSampler(texture - GL_TEXTURE0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002717}
2718
2719void Context::blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2720{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002721 mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
Jamie Madillc20ab272016-06-09 07:20:46 -07002722}
2723
2724void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
2725{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002726 mGLState.setBlendEquation(modeRGB, modeAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002727}
2728
2729void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
2730{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002731 mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002732}
2733
2734void Context::clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2735{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002736 mGLState.setColorClearValue(red, green, blue, alpha);
Jamie Madillc20ab272016-06-09 07:20:46 -07002737}
2738
2739void Context::clearDepthf(GLclampf depth)
2740{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002741 mGLState.setDepthClearValue(depth);
Jamie Madillc20ab272016-06-09 07:20:46 -07002742}
2743
2744void Context::clearStencil(GLint s)
2745{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002746 mGLState.setStencilClearValue(s);
Jamie Madillc20ab272016-06-09 07:20:46 -07002747}
2748
2749void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
2750{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002751 mGLState.setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002752}
2753
2754void Context::cullFace(GLenum mode)
2755{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002756 mGLState.setCullMode(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002757}
2758
2759void Context::depthFunc(GLenum func)
2760{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002761 mGLState.setDepthFunc(func);
Jamie Madillc20ab272016-06-09 07:20:46 -07002762}
2763
2764void Context::depthMask(GLboolean flag)
2765{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002766 mGLState.setDepthMask(flag != GL_FALSE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002767}
2768
2769void Context::depthRangef(GLclampf zNear, GLclampf zFar)
2770{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002771 mGLState.setDepthRange(zNear, zFar);
Jamie Madillc20ab272016-06-09 07:20:46 -07002772}
2773
2774void Context::disable(GLenum cap)
2775{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002776 mGLState.setEnableFeature(cap, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002777}
2778
2779void Context::disableVertexAttribArray(GLuint index)
2780{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002781 mGLState.setEnableVertexAttribArray(index, false);
Jamie Madillc20ab272016-06-09 07:20:46 -07002782}
2783
2784void Context::enable(GLenum cap)
2785{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002786 mGLState.setEnableFeature(cap, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002787}
2788
2789void Context::enableVertexAttribArray(GLuint index)
2790{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002791 mGLState.setEnableVertexAttribArray(index, true);
Jamie Madillc20ab272016-06-09 07:20:46 -07002792}
2793
2794void Context::frontFace(GLenum mode)
2795{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002796 mGLState.setFrontFace(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002797}
2798
2799void Context::hint(GLenum target, GLenum mode)
2800{
2801 switch (target)
2802 {
2803 case GL_GENERATE_MIPMAP_HINT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002804 mGLState.setGenerateMipmapHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002805 break;
2806
2807 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002808 mGLState.setFragmentShaderDerivativeHint(mode);
Jamie Madillc20ab272016-06-09 07:20:46 -07002809 break;
2810
2811 default:
2812 UNREACHABLE();
2813 return;
2814 }
2815}
2816
2817void Context::lineWidth(GLfloat width)
2818{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002819 mGLState.setLineWidth(width);
Jamie Madillc20ab272016-06-09 07:20:46 -07002820}
2821
2822void Context::pixelStorei(GLenum pname, GLint param)
2823{
2824 switch (pname)
2825 {
2826 case GL_UNPACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002827 mGLState.setUnpackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002828 break;
2829
2830 case GL_PACK_ALIGNMENT:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002831 mGLState.setPackAlignment(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002832 break;
2833
2834 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002835 mGLState.setPackReverseRowOrder(param != 0);
Jamie Madillc20ab272016-06-09 07:20:46 -07002836 break;
2837
2838 case GL_UNPACK_ROW_LENGTH:
2839 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002840 mGLState.setUnpackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002841 break;
2842
2843 case GL_UNPACK_IMAGE_HEIGHT:
2844 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002845 mGLState.setUnpackImageHeight(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002846 break;
2847
2848 case GL_UNPACK_SKIP_IMAGES:
2849 ASSERT(getClientVersion() >= 3);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 mGLState.setUnpackSkipImages(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002851 break;
2852
2853 case GL_UNPACK_SKIP_ROWS:
2854 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002855 mGLState.setUnpackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002856 break;
2857
2858 case GL_UNPACK_SKIP_PIXELS:
2859 ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002860 mGLState.setUnpackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002861 break;
2862
2863 case GL_PACK_ROW_LENGTH:
2864 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002865 mGLState.setPackRowLength(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002866 break;
2867
2868 case GL_PACK_SKIP_ROWS:
2869 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002870 mGLState.setPackSkipRows(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002871 break;
2872
2873 case GL_PACK_SKIP_PIXELS:
2874 ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002875 mGLState.setPackSkipPixels(param);
Jamie Madillc20ab272016-06-09 07:20:46 -07002876 break;
2877
2878 default:
2879 UNREACHABLE();
2880 return;
2881 }
2882}
2883
2884void Context::polygonOffset(GLfloat factor, GLfloat units)
2885{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002886 mGLState.setPolygonOffsetParams(factor, units);
Jamie Madillc20ab272016-06-09 07:20:46 -07002887}
2888
2889void Context::sampleCoverage(GLclampf value, GLboolean invert)
2890{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002891 mGLState.setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
Jamie Madillc20ab272016-06-09 07:20:46 -07002892}
2893
2894void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2895{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002896 mGLState.setScissorParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002897}
2898
2899void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2900{
2901 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2902 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002903 mGLState.setStencilParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002904 }
2905
2906 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2907 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002908 mGLState.setStencilBackParams(func, ref, mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002909 }
2910}
2911
2912void Context::stencilMaskSeparate(GLenum face, GLuint mask)
2913{
2914 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2915 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002916 mGLState.setStencilWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002917 }
2918
2919 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2920 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002921 mGLState.setStencilBackWritemask(mask);
Jamie Madillc20ab272016-06-09 07:20:46 -07002922 }
2923}
2924
2925void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
2926{
2927 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
2928 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002929 mGLState.setStencilOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002930 }
2931
2932 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
2933 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002934 mGLState.setStencilBackOperations(fail, zfail, zpass);
Jamie Madillc20ab272016-06-09 07:20:46 -07002935 }
2936}
2937
2938void Context::vertexAttrib1f(GLuint index, GLfloat x)
2939{
2940 GLfloat vals[4] = {x, 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002941 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002942}
2943
2944void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
2945{
2946 GLfloat vals[4] = {values[0], 0, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002947 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002948}
2949
2950void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
2951{
2952 GLfloat vals[4] = {x, y, 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002953 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002954}
2955
2956void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
2957{
2958 GLfloat vals[4] = {values[0], values[1], 0, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002959 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002960}
2961
2962void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
2963{
2964 GLfloat vals[4] = {x, y, z, 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002965 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002966}
2967
2968void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
2969{
2970 GLfloat vals[4] = {values[0], values[1], values[2], 1};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002971 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002972}
2973
2974void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2975{
2976 GLfloat vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 mGLState.setVertexAttribf(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07002978}
2979
2980void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
2981{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002982 mGLState.setVertexAttribf(index, values);
Jamie Madillc20ab272016-06-09 07:20:46 -07002983}
2984
2985void Context::vertexAttribPointer(GLuint index,
2986 GLint size,
2987 GLenum type,
2988 GLboolean normalized,
2989 GLsizei stride,
2990 const GLvoid *ptr)
2991{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002992 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
2993 normalized == GL_TRUE, false, stride, ptr);
Jamie Madillc20ab272016-06-09 07:20:46 -07002994}
2995
2996void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
2997{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002998 mGLState.setViewportParams(x, y, width, height);
Jamie Madillc20ab272016-06-09 07:20:46 -07002999}
3000
3001void Context::vertexAttribIPointer(GLuint index,
3002 GLint size,
3003 GLenum type,
3004 GLsizei stride,
3005 const GLvoid *pointer)
3006{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003007 mGLState.setVertexAttribState(index, mGLState.getTargetBuffer(GL_ARRAY_BUFFER), size, type,
3008 false, true, stride, pointer);
Jamie Madillc20ab272016-06-09 07:20:46 -07003009}
3010
3011void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
3012{
3013 GLint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003014 mGLState.setVertexAttribi(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003015}
3016
3017void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
3018{
3019 GLuint vals[4] = {x, y, z, w};
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003020 mGLState.setVertexAttribu(index, vals);
Jamie Madillc20ab272016-06-09 07:20:46 -07003021}
3022
3023void Context::vertexAttribI4iv(GLuint index, const GLint *v)
3024{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003025 mGLState.setVertexAttribi(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003026}
3027
3028void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
3029{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003030 mGLState.setVertexAttribu(index, v);
Jamie Madillc20ab272016-06-09 07:20:46 -07003031}
3032
3033void Context::debugMessageControl(GLenum source,
3034 GLenum type,
3035 GLenum severity,
3036 GLsizei count,
3037 const GLuint *ids,
3038 GLboolean enabled)
3039{
3040 std::vector<GLuint> idVector(ids, ids + count);
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003041 mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
3042 (enabled != GL_FALSE));
Jamie Madillc20ab272016-06-09 07:20:46 -07003043}
3044
3045void Context::debugMessageInsert(GLenum source,
3046 GLenum type,
3047 GLuint id,
3048 GLenum severity,
3049 GLsizei length,
3050 const GLchar *buf)
3051{
3052 std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003053 mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003054}
3055
3056void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
3057{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003058 mGLState.getDebug().setCallback(callback, userParam);
Jamie Madillc20ab272016-06-09 07:20:46 -07003059}
3060
3061GLuint Context::getDebugMessageLog(GLuint count,
3062 GLsizei bufSize,
3063 GLenum *sources,
3064 GLenum *types,
3065 GLuint *ids,
3066 GLenum *severities,
3067 GLsizei *lengths,
3068 GLchar *messageLog)
3069{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003070 return static_cast<GLuint>(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids,
3071 severities, lengths, messageLog));
Jamie Madillc20ab272016-06-09 07:20:46 -07003072}
3073
3074void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
3075{
3076 std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003077 mGLState.getDebug().pushGroup(source, id, std::move(msg));
Jamie Madillc20ab272016-06-09 07:20:46 -07003078}
3079
3080void Context::popDebugGroup()
3081{
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003082 mGLState.getDebug().popGroup();
Jamie Madillc20ab272016-06-09 07:20:46 -07003083}
3084
Jamie Madillc29968b2016-01-20 11:17:23 -05003085} // namespace gl