blob: 4330803d7ce20fb91255e1f3f06022e174a88e4d [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>
14
Geoff Lang0b7eef72014-06-12 14:10:47 -040015#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050016#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050018#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050019#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Fence.h"
21#include "libANGLE/Framebuffer.h"
22#include "libANGLE/FramebufferAttachment.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050025#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050026#include "libANGLE/ResourceManager.h"
27#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050028#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Texture.h"
30#include "libANGLE/TransformFeedback.h"
31#include "libANGLE/VertexArray.h"
32#include "libANGLE/formatutils.h"
33#include "libANGLE/validationES.h"
Jamie Madill437fa652016-05-03 15:13:24 -040034#include "libANGLE/renderer/ContextImpl.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050035#include "libANGLE/renderer/Renderer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000036
Geoff Langf6db0982015-08-25 13:04:00 -040037namespace
38{
39
Ian Ewell3ffd78b2016-01-22 16:09:42 -050040template <typename T>
41gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
42{
43 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
44 ASSERT(queryObject != nullptr);
45
46 switch (pname)
47 {
48 case GL_QUERY_RESULT_EXT:
49 return queryObject->getResult(params);
50 case GL_QUERY_RESULT_AVAILABLE_EXT:
51 {
52 bool available;
53 gl::Error error = queryObject->isResultAvailable(&available);
54 if (!error.isError())
55 {
56 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
57 }
58 return error;
59 }
60 default:
61 UNREACHABLE();
62 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
63 }
64}
65
Geoff Langf6db0982015-08-25 13:04:00 -040066void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
67{
Geoff Lang1a683462015-09-29 15:09:59 -040068 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040069 {
70 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
71 tfBufferIndex++)
72 {
73 const OffsetBindingPointer<gl::Buffer> &buffer =
74 transformFeedback->getIndexedBuffer(tfBufferIndex);
75 if (buffer.get() != nullptr)
76 {
77 buffer->onTransformFeedback();
78 }
79 }
80 }
81}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050082
83// Attribute map queries.
84EGLint GetClientVersion(const egl::AttributeMap &attribs)
85{
Ian Ewellec2c0c52016-04-05 13:46:26 -040086 return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
Jamie Madill46e6c7a2016-01-18 14:42:30 -050087}
88
89GLenum GetResetStrategy(const egl::AttributeMap &attribs)
90{
Ian Ewellec2c0c52016-04-05 13:46:26 -040091 EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
92 EGL_NO_RESET_NOTIFICATION_EXT);
Jamie Madill46e6c7a2016-01-18 14:42:30 -050093 switch (attrib)
94 {
95 case EGL_NO_RESET_NOTIFICATION:
96 return GL_NO_RESET_NOTIFICATION_EXT;
97 case EGL_LOSE_CONTEXT_ON_RESET:
98 return GL_LOSE_CONTEXT_ON_RESET_EXT;
99 default:
100 UNREACHABLE();
101 return GL_NONE;
102 }
103}
104
105bool GetRobustAccess(const egl::AttributeMap &attribs)
106{
107 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
108}
109
110bool GetDebug(const egl::AttributeMap &attribs)
111{
112 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
113}
114
115bool GetNoError(const egl::AttributeMap &attribs)
116{
117 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
118}
119
Geoff Langf6db0982015-08-25 13:04:00 -0400120} // anonymous namespace
121
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000122namespace gl
123{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000124
Corentin Wallez51706ea2015-08-07 14:39:22 -0400125Context::Context(const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400126 const Context *shareContext,
127 rx::Renderer *renderer,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500128 const egl::AttributeMap &attribs)
129 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500130 mState,
131 mCaps,
132 mTextureCaps,
133 mExtensions,
134 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500135 mLimitations,
136 GetNoError(attribs)),
Jamie Madill8415b5f2016-04-26 13:41:39 -0400137 mImplementation(renderer->createContext(getData())),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mCompiler(nullptr),
Jamie Madillf25855c2015-11-03 11:06:18 -0500139 mRenderer(renderer),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400141 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500142 mClientType(EGL_OPENGL_ES_API),
143 mHasBeenCurrent(false),
144 mContextLost(false),
145 mResetStatus(GL_NO_ERROR),
146 mResetStrategy(GetResetStrategy(attribs)),
147 mRobustAccess(GetRobustAccess(attribs)),
148 mCurrentSurface(nullptr),
149 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000150{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000152
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400154
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500155 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100156
Shannon Woods53a94a82014-06-24 15:20:36 -0400157 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400158
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000159 if (shareContext != NULL)
160 {
161 mResourceManager = shareContext->mResourceManager;
162 mResourceManager->addRef();
163 }
164 else
165 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000166 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000167 }
168
Jamie Madillc185cb82015-04-28 12:39:08 -0400169 mData.resourceManager = mResourceManager;
170
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000171 // [OpenGL ES 2.0.24] section 3.7 page 83:
172 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
173 // and cube map texture state vectors respectively associated with them.
174 // In order that access to these initial textures not be lost, they are treated as texture
175 // objects all of whose names are 0.
176
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300177 Texture *zeroTexture2D = new Texture(mRenderer, 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500178 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500179
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300180 Texture *zeroTextureCube = new Texture(mRenderer, 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500181 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400182
183 if (mClientVersion >= 3)
184 {
185 // TODO: These could also be enabled via extension
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300186 Texture *zeroTexture3D = new Texture(mRenderer, 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500187 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400188
Olli Etuaho82c47ad2016-04-20 18:28:47 +0300189 Texture *zeroTexture2DArray = new Texture(mRenderer, 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500190 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400191 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000192
Ian Ewellbda75592016-04-18 17:25:54 -0400193 if (mExtensions.eglImageExternal || mExtensions.eglStreamConsumerExternal)
194 {
195 Texture *zeroTextureExternal = new Texture(mRenderer, 0, GL_TEXTURE_EXTERNAL_OES);
196 mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(zeroTextureExternal);
197 }
198
Jamie Madille6382c32014-11-07 15:05:26 -0500199 mState.initializeZeroTextures(mZeroTextures);
200
Jamie Madill57a89722013-07-02 11:57:03 -0400201 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000202 bindArrayBuffer(0);
203 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400204
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205 bindRenderbuffer(0);
206
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000207 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400208 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000209 {
210 bindIndexedUniformBuffer(0, i, 0, -1);
211 }
212
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000213 bindCopyReadBuffer(0);
214 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000215 bindPixelPackBuffer(0);
216 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000217
Geoff Lang1a683462015-09-29 15:09:59 -0400218 if (mClientVersion >= 3)
219 {
220 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
221 // In the initial state, a default transform feedback object is bound and treated as
222 // a transform feedback object with a name of zero. That object is bound any time
223 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400224 bindTransformFeedback(0);
225 }
Geoff Langc8058452014-02-03 12:04:11 -0500226
Jamie Madill83f349e2015-09-23 09:50:36 -0400227 mCompiler = new Compiler(mRenderer, getData());
Jamie Madillad9f24e2016-02-12 09:27:24 -0500228
229 // Initialize dirty bit masks
230 // TODO(jmadill): additional ES3 state
231 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
232 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
233 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
234 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
235 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
236 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400237 mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500238 // No dirty objects.
239
240 // Readpixels uses the pack state and read FBO
241 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
242 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
243 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
244 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
245 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
Corentin Wallezbbd663a2016-04-20 17:49:17 -0400246 mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
Jamie Madillad9f24e2016-02-12 09:27:24 -0500247 mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
248
249 mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
250 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
251 mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
252 mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
253 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
254 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
255 mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
256 mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
257 mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
258 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
259 mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
260 mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
261
262 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
263 mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
264 mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
265 mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Jamie Madill437fa652016-05-03 15:13:24 -0400266
267 handleError(mImplementation->initialize(renderer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268}
269
270Context::~Context()
271{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500272 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000273
Corentin Wallez37c39792015-08-20 14:19:46 -0400274 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000275 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400276 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400277 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400278 {
279 SafeDelete(framebuffer.second);
280 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281 }
282
Corentin Wallez80b24112015-08-25 16:41:57 -0400283 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400285 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286 }
287
Corentin Wallez80b24112015-08-25 16:41:57 -0400288 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000289 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400290 if (query.second != nullptr)
291 {
292 query.second->release();
293 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000294 }
295
Corentin Wallez80b24112015-08-25 16:41:57 -0400296 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400297 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400298 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400299 }
300
Corentin Wallez80b24112015-08-25 16:41:57 -0400301 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500302 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500303 if (transformFeedback.second != nullptr)
304 {
305 transformFeedback.second->release();
306 }
Geoff Langc8058452014-02-03 12:04:11 -0500307 }
308
Jamie Madilldedd7b92014-11-05 16:30:36 -0500309 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400310 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500311 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400312 }
313 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000314
Corentin Wallez51706ea2015-08-07 14:39:22 -0400315 if (mCurrentSurface != nullptr)
316 {
317 releaseSurface();
318 }
319
Jamie Madill1e9ae072014-11-06 15:27:21 -0500320 if (mResourceManager)
321 {
322 mResourceManager->release();
323 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500324
325 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000326}
327
daniel@transgaming.comad629872012-11-28 19:32:06 +0000328void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000329{
Jamie Madill77a72f62015-04-14 11:18:32 -0400330 ASSERT(surface != nullptr);
331
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000332 if (!mHasBeenCurrent)
333 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400335 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000336
Shannon Woods53a94a82014-06-24 15:20:36 -0400337 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
338 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000339
340 mHasBeenCurrent = true;
341 }
342
Jamie Madill1b94d432015-08-07 13:23:23 -0400343 // TODO(jmadill): Rework this when we support ContextImpl
344 mState.setAllDirtyBits();
345
Corentin Wallez51706ea2015-08-07 14:39:22 -0400346 if (mCurrentSurface)
347 {
348 releaseSurface();
349 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000350 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400351 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000352
Corentin Wallez37c39792015-08-20 14:19:46 -0400353 // Update default framebuffer, the binding of the previous default
354 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400355 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400356 Framebuffer *newDefault = surface->getDefaultFramebuffer();
357 if (mState.getReadFramebuffer() == nullptr)
358 {
359 mState.setReadFramebufferBinding(newDefault);
360 }
361 if (mState.getDrawFramebuffer() == nullptr)
362 {
363 mState.setDrawFramebufferBinding(newDefault);
364 }
365 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400366 }
Ian Ewell292f0052016-02-04 10:37:32 -0500367
368 // Notify the renderer of a context switch
369 mRenderer->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000370}
371
Jamie Madill77a72f62015-04-14 11:18:32 -0400372void Context::releaseSurface()
373{
Corentin Wallez37c39792015-08-20 14:19:46 -0400374 ASSERT(mCurrentSurface != nullptr);
375
376 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400377 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400378 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
379 if (mState.getReadFramebuffer() == currentDefault)
380 {
381 mState.setReadFramebufferBinding(nullptr);
382 }
383 if (mState.getDrawFramebuffer() == currentDefault)
384 {
385 mState.setDrawFramebufferBinding(nullptr);
386 }
387 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400388 }
389
Corentin Wallez51706ea2015-08-07 14:39:22 -0400390 mCurrentSurface->setIsCurrent(false);
391 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400392}
393
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000394// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000395void Context::markContextLost()
396{
397 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
398 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
399 mContextLost = true;
400}
401
402bool Context::isContextLost()
403{
404 return mContextLost;
405}
406
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407GLuint Context::createBuffer()
408{
409 return mResourceManager->createBuffer();
410}
411
412GLuint Context::createProgram()
413{
414 return mResourceManager->createProgram();
415}
416
417GLuint Context::createShader(GLenum type)
418{
Jamie Madill006cbc52015-09-23 16:47:54 -0400419 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420}
421
422GLuint Context::createTexture()
423{
424 return mResourceManager->createTexture();
425}
426
427GLuint Context::createRenderbuffer()
428{
429 return mResourceManager->createRenderbuffer();
430}
431
Geoff Lang882033e2014-09-30 11:26:07 -0400432GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400433{
434 GLuint handle = mResourceManager->createFenceSync();
435
Cooper Partind8e62a32015-01-29 15:21:25 -0800436 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400437}
438
Jamie Madill57a89722013-07-02 11:57:03 -0400439GLuint Context::createVertexArray()
440{
Geoff Lang36167ab2015-12-07 10:27:14 -0500441 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
442 mVertexArrayMap[vertexArray] = nullptr;
443 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400444}
445
Jamie Madilldc356042013-07-19 16:36:57 -0400446GLuint Context::createSampler()
447{
448 return mResourceManager->createSampler();
449}
450
Geoff Langc8058452014-02-03 12:04:11 -0500451GLuint Context::createTransformFeedback()
452{
Geoff Lang36167ab2015-12-07 10:27:14 -0500453 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
454 mTransformFeedbackMap[transformFeedback] = nullptr;
455 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500456}
457
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458// Returns an unused framebuffer name
459GLuint Context::createFramebuffer()
460{
461 GLuint handle = mFramebufferHandleAllocator.allocate();
462
463 mFramebufferMap[handle] = NULL;
464
465 return handle;
466}
467
Jamie Madill33dc8432013-07-26 11:55:05 -0400468GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000469{
Jamie Madill33dc8432013-07-26 11:55:05 -0400470 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000471
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700472 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473
474 return handle;
475}
476
477// Returns an unused query name
478GLuint Context::createQuery()
479{
480 GLuint handle = mQueryHandleAllocator.allocate();
481
482 mQueryMap[handle] = NULL;
483
484 return handle;
485}
486
487void Context::deleteBuffer(GLuint buffer)
488{
489 if (mResourceManager->getBuffer(buffer))
490 {
491 detachBuffer(buffer);
492 }
Jamie Madill893ab082014-05-16 16:56:10 -0400493
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000494 mResourceManager->deleteBuffer(buffer);
495}
496
497void Context::deleteShader(GLuint shader)
498{
499 mResourceManager->deleteShader(shader);
500}
501
502void Context::deleteProgram(GLuint program)
503{
504 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000505}
506
507void Context::deleteTexture(GLuint texture)
508{
509 if (mResourceManager->getTexture(texture))
510 {
511 detachTexture(texture);
512 }
513
514 mResourceManager->deleteTexture(texture);
515}
516
517void Context::deleteRenderbuffer(GLuint renderbuffer)
518{
519 if (mResourceManager->getRenderbuffer(renderbuffer))
520 {
521 detachRenderbuffer(renderbuffer);
522 }
Jamie Madill893ab082014-05-16 16:56:10 -0400523
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524 mResourceManager->deleteRenderbuffer(renderbuffer);
525}
526
Jamie Madillcd055f82013-07-26 11:55:15 -0400527void Context::deleteFenceSync(GLsync fenceSync)
528{
529 // The spec specifies the underlying Fence object is not deleted until all current
530 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
531 // and since our API is currently designed for being called from a single thread, we can delete
532 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700533 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400534}
535
Jamie Madill57a89722013-07-02 11:57:03 -0400536void Context::deleteVertexArray(GLuint vertexArray)
537{
Geoff Lang36167ab2015-12-07 10:27:14 -0500538 auto iter = mVertexArrayMap.find(vertexArray);
539 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000540 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500541 VertexArray *vertexArrayObject = iter->second;
542 if (vertexArrayObject != nullptr)
543 {
544 detachVertexArray(vertexArray);
545 delete vertexArrayObject;
546 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000547
Geoff Lang36167ab2015-12-07 10:27:14 -0500548 mVertexArrayMap.erase(iter);
549 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400550 }
551}
552
Jamie Madilldc356042013-07-19 16:36:57 -0400553void Context::deleteSampler(GLuint sampler)
554{
555 if (mResourceManager->getSampler(sampler))
556 {
557 detachSampler(sampler);
558 }
559
560 mResourceManager->deleteSampler(sampler);
561}
562
Geoff Langc8058452014-02-03 12:04:11 -0500563void Context::deleteTransformFeedback(GLuint transformFeedback)
564{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500565 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500566 if (iter != mTransformFeedbackMap.end())
567 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500568 TransformFeedback *transformFeedbackObject = iter->second;
569 if (transformFeedbackObject != nullptr)
570 {
571 detachTransformFeedback(transformFeedback);
572 transformFeedbackObject->release();
573 }
574
Geoff Lang50b3fe82015-12-08 14:49:12 +0000575 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500576 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500577 }
578}
579
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580void Context::deleteFramebuffer(GLuint framebuffer)
581{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500582 auto framebufferObject = mFramebufferMap.find(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583
584 if (framebufferObject != mFramebufferMap.end())
585 {
586 detachFramebuffer(framebuffer);
587
588 mFramebufferHandleAllocator.release(framebufferObject->first);
589 delete framebufferObject->second;
590 mFramebufferMap.erase(framebufferObject);
591 }
592}
593
Jamie Madill33dc8432013-07-26 11:55:05 -0400594void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000595{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500596 auto fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000597
Jamie Madill33dc8432013-07-26 11:55:05 -0400598 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400600 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000601 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400602 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000603 }
604}
605
606void Context::deleteQuery(GLuint query)
607{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500608 auto queryObject = mQueryMap.find(query);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000609 if (queryObject != mQueryMap.end())
610 {
611 mQueryHandleAllocator.release(queryObject->first);
612 if (queryObject->second)
613 {
614 queryObject->second->release();
615 }
616 mQueryMap.erase(queryObject);
617 }
618}
619
Geoff Lang70d0f492015-12-10 17:45:46 -0500620Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621{
622 return mResourceManager->getBuffer(handle);
623}
624
Geoff Lang48dcae72014-02-05 16:28:24 -0500625Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626{
627 return mResourceManager->getShader(handle);
628}
629
Geoff Lang48dcae72014-02-05 16:28:24 -0500630Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000631{
632 return mResourceManager->getProgram(handle);
633}
634
Jamie Madill570f7c82014-07-03 10:38:54 -0400635Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000636{
637 return mResourceManager->getTexture(handle);
638}
639
Geoff Lang70d0f492015-12-10 17:45:46 -0500640Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000641{
642 return mResourceManager->getRenderbuffer(handle);
643}
644
Jamie Madillcd055f82013-07-26 11:55:15 -0400645FenceSync *Context::getFenceSync(GLsync handle) const
646{
Minmin Gong794e0002015-04-07 18:31:54 -0700647 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400648}
649
Jamie Madill57a89722013-07-02 11:57:03 -0400650VertexArray *Context::getVertexArray(GLuint handle) const
651{
652 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500653 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400654}
655
Jamie Madilldc356042013-07-19 16:36:57 -0400656Sampler *Context::getSampler(GLuint handle) const
657{
658 return mResourceManager->getSampler(handle);
659}
660
Geoff Langc8058452014-02-03 12:04:11 -0500661TransformFeedback *Context::getTransformFeedback(GLuint handle) const
662{
Geoff Lang36167ab2015-12-07 10:27:14 -0500663 auto iter = mTransformFeedbackMap.find(handle);
664 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500665}
666
Geoff Lang70d0f492015-12-10 17:45:46 -0500667LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
668{
669 switch (identifier)
670 {
671 case GL_BUFFER:
672 return getBuffer(name);
673 case GL_SHADER:
674 return getShader(name);
675 case GL_PROGRAM:
676 return getProgram(name);
677 case GL_VERTEX_ARRAY:
678 return getVertexArray(name);
679 case GL_QUERY:
680 return getQuery(name);
681 case GL_TRANSFORM_FEEDBACK:
682 return getTransformFeedback(name);
683 case GL_SAMPLER:
684 return getSampler(name);
685 case GL_TEXTURE:
686 return getTexture(name);
687 case GL_RENDERBUFFER:
688 return getRenderbuffer(name);
689 case GL_FRAMEBUFFER:
690 return getFramebuffer(name);
691 default:
692 UNREACHABLE();
693 return nullptr;
694 }
695}
696
697LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
698{
699 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
700}
701
Jamie Madilldc356042013-07-19 16:36:57 -0400702bool Context::isSampler(GLuint samplerName) const
703{
704 return mResourceManager->isSampler(samplerName);
705}
706
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500707void Context::bindArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000708{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500709 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
710 mState.setArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000711}
712
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500713void Context::bindElementArrayBuffer(GLuint bufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500715 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
716 mState.getVertexArray()->setElementArrayBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000717}
718
Jamie Madilldedd7b92014-11-05 16:30:36 -0500719void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000720{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500721 Texture *texture = nullptr;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000722
Jamie Madilldedd7b92014-11-05 16:30:36 -0500723 if (handle == 0)
724 {
725 texture = mZeroTextures[target].get();
726 }
727 else
728 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500729 texture = mResourceManager->checkTextureAllocation(handle, target);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500730 }
731
732 ASSERT(texture);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500733 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000734}
735
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500736void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000737{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500738 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
739 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000740}
741
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500742void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000743{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500744 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
745 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000746}
747
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500748void Context::bindRenderbuffer(GLuint renderbufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000749{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500750 Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle);
751 mState.setRenderbufferBinding(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000752}
753
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500754void Context::bindVertexArray(GLuint vertexArrayHandle)
Jamie Madill57a89722013-07-02 11:57:03 -0400755{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500756 VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
757 mState.setVertexArrayBinding(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400758}
759
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500760void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle)
Jamie Madilldc356042013-07-19 16:36:57 -0400761{
Geoff Lang76b10c92014-09-05 16:28:14 -0400762 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500763 Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle);
764 mState.setSamplerBinding(textureUnit, sampler);
Jamie Madilldc356042013-07-19 16:36:57 -0400765}
766
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500767void Context::bindGenericUniformBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000768{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500769 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
770 mState.setGenericUniformBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000771}
772
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500773void Context::bindIndexedUniformBuffer(GLuint bufferHandle,
774 GLuint index,
775 GLintptr offset,
776 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000777{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500778 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
779 mState.setIndexedUniformBufferBinding(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000780}
781
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500782void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000783{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500784 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
785 mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer);
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000786}
787
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500788void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle,
789 GLuint index,
790 GLintptr offset,
791 GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000792{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500793 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
794 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000795}
796
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500797void Context::bindCopyReadBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000798{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500799 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
800 mState.setCopyReadBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000801}
802
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500803void Context::bindCopyWriteBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000804{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500805 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
806 mState.setCopyWriteBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000807}
808
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500809void Context::bindPixelPackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000810{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500811 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
812 mState.setPixelPackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000813}
814
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500815void Context::bindPixelUnpackBuffer(GLuint bufferHandle)
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000816{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500817 Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle);
818 mState.setPixelUnpackBufferBinding(buffer);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000819}
820
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821void Context::useProgram(GLuint program)
822{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500823 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000824}
825
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500826void Context::bindTransformFeedback(GLuint transformFeedbackHandle)
Geoff Langc8058452014-02-03 12:04:11 -0500827{
Jamie Madill3f01e6c2016-03-08 13:53:02 -0500828 TransformFeedback *transformFeedback =
829 checkTransformFeedbackAllocation(transformFeedbackHandle);
830 mState.setTransformFeedbackBinding(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500831}
832
Geoff Lang5aad9672014-09-08 11:10:42 -0400833Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000834{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000835 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400836 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000837
Geoff Lang5aad9672014-09-08 11:10:42 -0400838 // begin query
839 Error error = queryObject->begin();
840 if (error.isError())
841 {
842 return error;
843 }
844
845 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400846 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000847
Geoff Lang5aad9672014-09-08 11:10:42 -0400848 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000849}
850
Geoff Lang5aad9672014-09-08 11:10:42 -0400851Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852{
Shannon Woods53a94a82014-06-24 15:20:36 -0400853 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400854 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855
Geoff Lang5aad9672014-09-08 11:10:42 -0400856 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857
Geoff Lang5aad9672014-09-08 11:10:42 -0400858 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400859 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400860
861 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000862}
863
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500864Error Context::queryCounter(GLuint id, GLenum target)
865{
866 ASSERT(target == GL_TIMESTAMP_EXT);
867
868 Query *queryObject = getQuery(id, true, target);
869 ASSERT(queryObject);
870
871 return queryObject->queryCounter();
872}
873
874void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
875{
876 switch (pname)
877 {
878 case GL_CURRENT_QUERY_EXT:
879 params[0] = getState().getActiveQueryId(target);
880 break;
881 case GL_QUERY_COUNTER_BITS_EXT:
882 switch (target)
883 {
884 case GL_TIME_ELAPSED_EXT:
885 params[0] = getExtensions().queryCounterBitsTimeElapsed;
886 break;
887 case GL_TIMESTAMP_EXT:
888 params[0] = getExtensions().queryCounterBitsTimestamp;
889 break;
890 default:
891 UNREACHABLE();
892 params[0] = 0;
893 break;
894 }
895 break;
896 default:
897 UNREACHABLE();
898 return;
899 }
900}
901
902Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
903{
904 return GetQueryObjectParameter(this, id, pname, params);
905}
906
907Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
908{
909 return GetQueryObjectParameter(this, id, pname, params);
910}
911
912Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
913{
914 return GetQueryObjectParameter(this, id, pname, params);
915}
916
917Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
918{
919 return GetQueryObjectParameter(this, id, pname, params);
920}
921
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500922Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000923{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500924 auto framebufferIt = mFramebufferMap.find(handle);
925 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000926}
927
Jamie Madill33dc8432013-07-26 11:55:05 -0400928FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500930 auto fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000931
Jamie Madill33dc8432013-07-26 11:55:05 -0400932 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000933 {
934 return NULL;
935 }
936 else
937 {
938 return fence->second;
939 }
940}
941
942Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
943{
Jamie Madill4e25a0d2016-03-08 13:53:03 -0500944 auto query = mQueryMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945
946 if (query == mQueryMap.end())
947 {
948 return NULL;
949 }
950 else
951 {
952 if (!query->second && create)
953 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700954 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000955 query->second->addRef();
956 }
957 return query->second;
958 }
959}
960
Geoff Lang70d0f492015-12-10 17:45:46 -0500961Query *Context::getQuery(GLuint handle) const
962{
963 auto iter = mQueryMap.find(handle);
964 return (iter != mQueryMap.end()) ? iter->second : nullptr;
965}
966
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500967Texture *Context::getTargetTexture(GLenum target) const
968{
Ian Ewellbda75592016-04-18 17:25:54 -0400969 ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500970 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000971}
972
Geoff Lang76b10c92014-09-05 16:28:14 -0400973Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500975 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000976}
977
Geoff Lang492a7e42014-11-05 13:27:06 -0500978Compiler *Context::getCompiler() const
979{
980 return mCompiler;
981}
982
Jamie Madill893ab082014-05-16 16:56:10 -0400983void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
985 switch (pname)
986 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000987 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000988 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000989 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400990 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400991 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000992 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993}
994
Jamie Madill893ab082014-05-16 16:56:10 -0400995void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000996{
Shannon Woods53a94a82014-06-24 15:20:36 -0400997 // Queries about context capabilities and maximums are answered by Context.
998 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999 switch (pname)
1000 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 params[0] = mCaps.minAliasedLineWidth;
1003 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 break;
1005 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001006 params[0] = mCaps.minAliasedPointSize;
1007 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001008 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001009 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001010 ASSERT(mExtensions.textureFilterAnisotropic);
1011 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001012 break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001013 case GL_MAX_TEXTURE_LOD_BIAS:
1014 *params = mCaps.maxLODBias;
1015 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001017 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001018 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020}
1021
Jamie Madill893ab082014-05-16 16:56:10 -04001022void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001023{
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 // Queries about context capabilities and maximums are answered by Context.
1025 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001026
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001027 switch (pname)
1028 {
Geoff Lang301d1612014-07-09 10:34:37 -04001029 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1030 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1031 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001032 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1033 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1034 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001035 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1036 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1037 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001038 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001039 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1040 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1041 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001042 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001043 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001044 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1045 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1046 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1047 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001048 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1049 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001050 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1051 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001052 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001053 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1054 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1055 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1056 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001057 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1058 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001059 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1060 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001061 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1062 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1063 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001064 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1065 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1066 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001067 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 case GL_MAX_VIEWPORT_DIMS:
1069 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001070 params[0] = mCaps.maxViewportWidth;
1071 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072 }
1073 break;
1074 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001075 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1078 *params = mResetStrategy;
1079 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001080 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001081 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001082 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001083 case GL_SHADER_BINARY_FORMATS:
1084 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1085 break;
1086 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001087 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001088 break;
1089 case GL_PROGRAM_BINARY_FORMATS:
1090 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001091 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001092 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001093 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001094 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001095
1096 // GL_KHR_debug
1097 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1098 *params = mExtensions.maxDebugMessageLength;
1099 break;
1100 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1101 *params = mExtensions.maxDebugLoggedMessages;
1102 break;
1103 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1104 *params = mExtensions.maxDebugGroupStackDepth;
1105 break;
1106 case GL_MAX_LABEL_LENGTH:
1107 *params = mExtensions.maxLabelLength;
1108 break;
1109
Ian Ewell53f59f42016-01-28 17:36:55 -05001110 // GL_EXT_disjoint_timer_query
1111 case GL_GPU_DISJOINT_EXT:
1112 *params = mRenderer->getGPUDisjoint();
1113 break;
1114
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001115 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001116 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001117 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001118 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001119}
1120
Jamie Madill893ab082014-05-16 16:56:10 -04001121void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001122{
Shannon Woods53a94a82014-06-24 15:20:36 -04001123 // Queries about context capabilities and maximums are answered by Context.
1124 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001125 switch (pname)
1126 {
1127 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001128 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001129 break;
1130 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001131 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001132 break;
1133 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001134 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001135 break;
1136 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001137 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001138 break;
1139 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001140 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001141 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001142
1143 // GL_EXT_disjoint_timer_query
1144 case GL_TIMESTAMP_EXT:
1145 *params = mRenderer->getTimestamp();
1146 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001147 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001148 UNREACHABLE();
1149 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001150 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001151}
1152
Geoff Lang70d0f492015-12-10 17:45:46 -05001153void Context::getPointerv(GLenum pname, void **params) const
1154{
1155 mState.getPointerv(pname, params);
1156}
1157
Shannon Woods1b2fb852013-08-19 14:28:48 -04001158bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1159{
Shannon Woods53a94a82014-06-24 15:20:36 -04001160 // Queries about context capabilities and maximums are answered by Context.
1161 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001162 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 // mere passthrough.
1164 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001165}
1166
1167bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1168{
Shannon Woods53a94a82014-06-24 15:20:36 -04001169 // Queries about context capabilities and maximums are answered by Context.
1170 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001171 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001172 // mere passthrough.
1173 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001174}
1175
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001176bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1177{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001178 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1179 {
1180 *type = GL_INT;
1181 *numParams = 1;
1182 return true;
1183 }
1184
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001185 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1186 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1187 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001188 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001189 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1190 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1191 // application.
1192 switch (pname)
1193 {
1194 case GL_COMPRESSED_TEXTURE_FORMATS:
1195 {
1196 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001197 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001198 }
1199 return true;
1200 case GL_PROGRAM_BINARY_FORMATS_OES:
1201 {
1202 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001203 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001204 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001205 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001206 case GL_SHADER_BINARY_FORMATS:
1207 {
1208 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001209 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001210 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001211 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001212
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001213 case GL_MAX_VERTEX_ATTRIBS:
1214 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1215 case GL_MAX_VARYING_VECTORS:
1216 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1217 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1218 case GL_MAX_TEXTURE_IMAGE_UNITS:
1219 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1220 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001221 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001222 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001223 case GL_NUM_SHADER_BINARY_FORMATS:
1224 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1225 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001226 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1227 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1228 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001229 case GL_RENDERBUFFER_BINDING:
1230 case GL_CURRENT_PROGRAM:
1231 case GL_PACK_ALIGNMENT:
1232 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1233 case GL_UNPACK_ALIGNMENT:
1234 case GL_GENERATE_MIPMAP_HINT:
1235 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1236 case GL_RED_BITS:
1237 case GL_GREEN_BITS:
1238 case GL_BLUE_BITS:
1239 case GL_ALPHA_BITS:
1240 case GL_DEPTH_BITS:
1241 case GL_STENCIL_BITS:
1242 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1243 case GL_CULL_FACE_MODE:
1244 case GL_FRONT_FACE:
1245 case GL_ACTIVE_TEXTURE:
1246 case GL_STENCIL_FUNC:
1247 case GL_STENCIL_VALUE_MASK:
1248 case GL_STENCIL_REF:
1249 case GL_STENCIL_FAIL:
1250 case GL_STENCIL_PASS_DEPTH_FAIL:
1251 case GL_STENCIL_PASS_DEPTH_PASS:
1252 case GL_STENCIL_BACK_FUNC:
1253 case GL_STENCIL_BACK_VALUE_MASK:
1254 case GL_STENCIL_BACK_REF:
1255 case GL_STENCIL_BACK_FAIL:
1256 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1257 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1258 case GL_DEPTH_FUNC:
1259 case GL_BLEND_SRC_RGB:
1260 case GL_BLEND_SRC_ALPHA:
1261 case GL_BLEND_DST_RGB:
1262 case GL_BLEND_DST_ALPHA:
1263 case GL_BLEND_EQUATION_RGB:
1264 case GL_BLEND_EQUATION_ALPHA:
1265 case GL_STENCIL_WRITEMASK:
1266 case GL_STENCIL_BACK_WRITEMASK:
1267 case GL_STENCIL_CLEAR_VALUE:
1268 case GL_SUBPIXEL_BITS:
1269 case GL_MAX_TEXTURE_SIZE:
1270 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1271 case GL_SAMPLE_BUFFERS:
1272 case GL_SAMPLES:
1273 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1274 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1275 case GL_TEXTURE_BINDING_2D:
1276 case GL_TEXTURE_BINDING_CUBE_MAP:
1277 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1278 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 {
1280 *type = GL_INT;
1281 *numParams = 1;
1282 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001283 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001284 case GL_MAX_SAMPLES_ANGLE:
1285 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001286 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001287 {
1288 *type = GL_INT;
1289 *numParams = 1;
1290 }
1291 else
1292 {
1293 return false;
1294 }
1295 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001296 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001297 case GL_MAX_VIEWPORT_DIMS:
1298 {
1299 *type = GL_INT;
1300 *numParams = 2;
1301 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001302 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001303 case GL_VIEWPORT:
1304 case GL_SCISSOR_BOX:
1305 {
1306 *type = GL_INT;
1307 *numParams = 4;
1308 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001309 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310 case GL_SHADER_COMPILER:
1311 case GL_SAMPLE_COVERAGE_INVERT:
1312 case GL_DEPTH_WRITEMASK:
1313 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1314 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1315 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1316 case GL_SAMPLE_COVERAGE:
1317 case GL_SCISSOR_TEST:
1318 case GL_STENCIL_TEST:
1319 case GL_DEPTH_TEST:
1320 case GL_BLEND:
1321 case GL_DITHER:
1322 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1323 {
1324 *type = GL_BOOL;
1325 *numParams = 1;
1326 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001327 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001328 case GL_COLOR_WRITEMASK:
1329 {
1330 *type = GL_BOOL;
1331 *numParams = 4;
1332 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001333 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001334 case GL_POLYGON_OFFSET_FACTOR:
1335 case GL_POLYGON_OFFSET_UNITS:
1336 case GL_SAMPLE_COVERAGE_VALUE:
1337 case GL_DEPTH_CLEAR_VALUE:
1338 case GL_LINE_WIDTH:
1339 {
1340 *type = GL_FLOAT;
1341 *numParams = 1;
1342 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001343 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001344 case GL_ALIASED_LINE_WIDTH_RANGE:
1345 case GL_ALIASED_POINT_SIZE_RANGE:
1346 case GL_DEPTH_RANGE:
1347 {
1348 *type = GL_FLOAT;
1349 *numParams = 2;
1350 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001351 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001352 case GL_COLOR_CLEAR_VALUE:
1353 case GL_BLEND_COLOR:
1354 {
1355 *type = GL_FLOAT;
1356 *numParams = 4;
1357 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001358 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001359 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001360 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001361 {
1362 return false;
1363 }
1364 *type = GL_FLOAT;
1365 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001366 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001367 case GL_TIMESTAMP_EXT:
1368 if (!mExtensions.disjointTimerQuery)
1369 {
1370 return false;
1371 }
1372 *type = GL_INT_64_ANGLEX;
1373 *numParams = 1;
1374 return true;
1375 case GL_GPU_DISJOINT_EXT:
1376 if (!mExtensions.disjointTimerQuery)
1377 {
1378 return false;
1379 }
1380 *type = GL_INT;
1381 *numParams = 1;
1382 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001383 }
1384
Geoff Lang70d0f492015-12-10 17:45:46 -05001385 if (mExtensions.debug)
1386 {
1387 switch (pname)
1388 {
1389 case GL_DEBUG_LOGGED_MESSAGES:
1390 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1391 case GL_DEBUG_GROUP_STACK_DEPTH:
1392 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1393 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1394 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1395 case GL_MAX_LABEL_LENGTH:
1396 *type = GL_INT;
1397 *numParams = 1;
1398 return true;
1399
1400 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1401 case GL_DEBUG_OUTPUT:
1402 *type = GL_BOOL;
1403 *numParams = 1;
1404 return true;
1405 }
1406 }
1407
Sami Väisänen74c23472016-05-09 17:30:30 +03001408 if (mExtensions.multisampleCompatibility)
1409 {
1410 switch (pname)
1411 {
1412 case GL_MULTISAMPLE_EXT:
1413 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1414 *type = GL_BOOL;
1415 *numParams = 1;
1416 return true;
1417 }
1418 }
1419
Austin Kinrossbc781f32015-10-26 09:27:38 -07001420 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1421 switch (pname)
1422 {
1423 case GL_PACK_ROW_LENGTH:
1424 case GL_PACK_SKIP_ROWS:
1425 case GL_PACK_SKIP_PIXELS:
1426 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1427 {
1428 return false;
1429 }
1430 *type = GL_INT;
1431 *numParams = 1;
1432 return true;
1433 case GL_UNPACK_ROW_LENGTH:
1434 case GL_UNPACK_SKIP_ROWS:
1435 case GL_UNPACK_SKIP_PIXELS:
1436 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1437 {
1438 return false;
1439 }
1440 *type = GL_INT;
1441 *numParams = 1;
1442 return true;
1443 case GL_VERTEX_ARRAY_BINDING:
1444 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1445 {
1446 return false;
1447 }
1448 *type = GL_INT;
1449 *numParams = 1;
1450 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001451 case GL_PIXEL_PACK_BUFFER_BINDING:
1452 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1453 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1454 {
1455 return false;
1456 }
1457 *type = GL_INT;
1458 *numParams = 1;
1459 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001460 }
1461
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001462 if (mClientVersion < 3)
1463 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001464 return false;
1465 }
1466
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001467 // Check for ES3.0+ parameter names
1468 switch (pname)
1469 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001470 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1471 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001472 case GL_UNIFORM_BUFFER_BINDING:
1473 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001474 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001475 case GL_COPY_READ_BUFFER_BINDING:
1476 case GL_COPY_WRITE_BUFFER_BINDING:
Olli Etuaho86821db2016-03-04 12:05:47 +02001477 case GL_SAMPLER_BINDING:
1478 case GL_READ_BUFFER:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001479 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001480 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001481 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001482 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001483 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1484 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1485 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001486 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1487 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001488 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001489 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1490 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001491 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1492 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001493 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001494 case GL_MAJOR_VERSION:
1495 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001496 case GL_MAX_ELEMENTS_INDICES:
1497 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001498 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001499 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001500 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001501 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001502 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001503 {
1504 *type = GL_INT;
1505 *numParams = 1;
1506 }
1507 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001508
1509 case GL_MAX_ELEMENT_INDEX:
1510 case GL_MAX_UNIFORM_BLOCK_SIZE:
1511 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1512 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1513 case GL_MAX_SERVER_WAIT_TIMEOUT:
1514 {
1515 *type = GL_INT_64_ANGLEX;
1516 *numParams = 1;
1517 }
1518 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001519
1520 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001521 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001522 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001523 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001524 {
1525 *type = GL_BOOL;
1526 *numParams = 1;
1527 }
1528 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001529
1530 case GL_MAX_TEXTURE_LOD_BIAS:
1531 {
1532 *type = GL_FLOAT;
1533 *numParams = 1;
1534 }
1535 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001536 }
1537
1538 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001539}
1540
Shannon Woods1b2fb852013-08-19 14:28:48 -04001541bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1542{
1543 if (mClientVersion < 3)
1544 {
1545 return false;
1546 }
1547
1548 switch (target)
1549 {
1550 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1551 case GL_UNIFORM_BUFFER_BINDING:
1552 {
1553 *type = GL_INT;
1554 *numParams = 1;
1555 }
1556 return true;
1557 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1558 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1559 case GL_UNIFORM_BUFFER_START:
1560 case GL_UNIFORM_BUFFER_SIZE:
1561 {
1562 *type = GL_INT_64_ANGLEX;
1563 *numParams = 1;
1564 }
1565 }
1566
1567 return false;
1568}
1569
Geoff Langf6db0982015-08-25 13:04:00 -04001570Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001571{
Jamie Madill1b94d432015-08-07 13:23:23 -04001572 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001573 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001574 if (error.isError())
1575 {
1576 return error;
1577 }
1578
Geoff Langf6db0982015-08-25 13:04:00 -04001579 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001580
1581 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001582}
1583
Geoff Langf6db0982015-08-25 13:04:00 -04001584Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1585{
1586 syncRendererState();
1587 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1588 if (error.isError())
1589 {
1590 return error;
1591 }
1592
1593 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1594
1595 return Error(GL_NO_ERROR);
1596}
1597
1598Error Context::drawElements(GLenum mode,
1599 GLsizei count,
1600 GLenum type,
1601 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001602 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001603{
Jamie Madill1b94d432015-08-07 13:23:23 -04001604 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001605 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1606}
1607
1608Error Context::drawElementsInstanced(GLenum mode,
1609 GLsizei count,
1610 GLenum type,
1611 const GLvoid *indices,
1612 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001613 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001614{
1615 syncRendererState();
1616 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1617 indexRange);
1618}
1619
1620Error Context::drawRangeElements(GLenum mode,
1621 GLuint start,
1622 GLuint end,
1623 GLsizei count,
1624 GLenum type,
1625 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001626 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001627{
1628 syncRendererState();
1629 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1630 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001631}
1632
Geoff Lang129753a2015-01-09 16:52:09 -05001633Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001634{
Geoff Lang129753a2015-01-09 16:52:09 -05001635 return mRenderer->flush();
1636}
1637
1638Error Context::finish()
1639{
1640 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001641}
1642
Austin Kinross6ee1e782015-05-29 17:05:37 -07001643void Context::insertEventMarker(GLsizei length, const char *marker)
1644{
1645 ASSERT(mRenderer);
1646 mRenderer->insertEventMarker(length, marker);
1647}
1648
1649void Context::pushGroupMarker(GLsizei length, const char *marker)
1650{
1651 ASSERT(mRenderer);
1652 mRenderer->pushGroupMarker(length, marker);
1653}
1654
1655void Context::popGroupMarker()
1656{
1657 ASSERT(mRenderer);
1658 mRenderer->popGroupMarker();
1659}
1660
Geoff Langd8605522016-04-13 10:19:12 -04001661void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
1662{
1663 Program *programObject = getProgram(program);
1664 ASSERT(programObject);
1665
1666 programObject->bindUniformLocation(location, name);
1667}
1668
Jamie Madill437fa652016-05-03 15:13:24 -04001669void Context::handleError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001670{
Geoff Langda5777c2014-07-11 09:52:58 -04001671 if (error.isError())
1672 {
1673 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001674
1675 if (!error.getMessage().empty())
1676 {
1677 auto &debug = mState.getDebug();
1678 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1679 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1680 }
Geoff Langda5777c2014-07-11 09:52:58 -04001681 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001682}
1683
1684// Get one of the recorded errors and clear its flag, if any.
1685// [OpenGL ES 2.0.24] section 2.5 page 13.
1686GLenum Context::getError()
1687{
Geoff Langda5777c2014-07-11 09:52:58 -04001688 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001689 {
Geoff Langda5777c2014-07-11 09:52:58 -04001690 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001691 }
Geoff Langda5777c2014-07-11 09:52:58 -04001692 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001693 {
Geoff Langda5777c2014-07-11 09:52:58 -04001694 GLenum error = *mErrors.begin();
1695 mErrors.erase(mErrors.begin());
1696 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001697 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001698}
1699
1700GLenum Context::getResetStatus()
1701{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001702 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001703 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001704 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001705 // mResetStatus will be set by the markContextLost callback
1706 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001707 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001708 {
1709 mRenderer->notifyDeviceLost();
1710 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001711 }
1712
1713 GLenum status = mResetStatus;
1714
1715 if (mResetStatus != GL_NO_ERROR)
1716 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001717 ASSERT(mContextLost);
1718
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001719 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001720 {
1721 mResetStatus = GL_NO_ERROR;
1722 }
1723 }
Jamie Madill893ab082014-05-16 16:56:10 -04001724
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001725 return status;
1726}
1727
1728bool Context::isResetNotificationEnabled()
1729{
1730 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1731}
1732
Corentin Walleze3b10e82015-05-20 11:06:25 -04001733const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001734{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001735 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001736}
1737
1738EGLenum Context::getClientType() const
1739{
1740 return mClientType;
1741}
1742
1743EGLenum Context::getRenderBuffer() const
1744{
Corentin Wallez37c39792015-08-20 14:19:46 -04001745 auto framebufferIt = mFramebufferMap.find(0);
1746 if (framebufferIt != mFramebufferMap.end())
1747 {
1748 const Framebuffer *framebuffer = framebufferIt->second;
1749 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1750
1751 ASSERT(backAttachment != nullptr);
1752 return backAttachment->getSurface()->getRenderBuffer();
1753 }
1754 else
1755 {
1756 return EGL_NONE;
1757 }
Régis Fénéon83107972015-02-05 12:57:44 +01001758}
1759
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001760VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001761{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001762 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001763 VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
1764 if (!vertexArray)
Geoff Lang36167ab2015-12-07 10:27:14 -05001765 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001766 vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS);
1767 mVertexArrayMap[vertexArrayHandle] = vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001768 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001769
1770 return vertexArray;
Geoff Lang36167ab2015-12-07 10:27:14 -05001771}
1772
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001773TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle)
Geoff Lang36167ab2015-12-07 10:27:14 -05001774{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001775 // Only called after a prior call to Gen.
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001776 TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
1777 if (!transformFeedback)
Geoff Lang36167ab2015-12-07 10:27:14 -05001778 {
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001779 transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps);
1780 transformFeedback->addRef();
1781 mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001782 }
Jamie Madill3f01e6c2016-03-08 13:53:02 -05001783
1784 return transformFeedback;
Geoff Lang36167ab2015-12-07 10:27:14 -05001785}
1786
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001787Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1788{
1789 // Can be called from Bind without a prior call to Gen.
1790 auto framebufferIt = mFramebufferMap.find(framebuffer);
1791 bool neverCreated = framebufferIt == mFramebufferMap.end();
1792 if (neverCreated || framebufferIt->second == nullptr)
1793 {
1794 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1795 if (neverCreated)
1796 {
1797 mFramebufferHandleAllocator.reserve(framebuffer);
1798 mFramebufferMap[framebuffer] = newFBO;
1799 return newFBO;
1800 }
1801
1802 framebufferIt->second = newFBO;
1803 }
1804
1805 return framebufferIt->second;
1806}
1807
Geoff Lang36167ab2015-12-07 10:27:14 -05001808bool Context::isVertexArrayGenerated(GLuint vertexArray)
1809{
1810 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1811}
1812
1813bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1814{
1815 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1816}
1817
Shannon Woods53a94a82014-06-24 15:20:36 -04001818void Context::detachTexture(GLuint texture)
1819{
1820 // Simple pass-through to State's detachTexture method, as textures do not require
1821 // allocation map management either here or in the resource manager at detach time.
1822 // Zero textures are held by the Context, and we don't attempt to request them from
1823 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001824 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001825}
1826
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001827void Context::detachBuffer(GLuint buffer)
1828{
Yuly Novikov5807a532015-12-03 13:01:22 -05001829 // Simple pass-through to State's detachBuffer method, since
1830 // only buffer attachments to container objects that are bound to the current context
1831 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001832
Yuly Novikov5807a532015-12-03 13:01:22 -05001833 // [OpenGL ES 3.2] section 5.1.2 page 45:
1834 // Attachments to unbound container objects, such as
1835 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1836 // are not affected and continue to act as references on the deleted object
1837 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001838}
1839
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001840void Context::detachFramebuffer(GLuint framebuffer)
1841{
Shannon Woods53a94a82014-06-24 15:20:36 -04001842 // Framebuffer detachment is handled by Context, because 0 is a valid
1843 // Framebuffer object, and a pointer to it must be passed from Context
1844 // to State at binding time.
1845
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001846 // [OpenGL ES 2.0.24] section 4.4 page 107:
1847 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1848 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1849
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001850 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001851 {
1852 bindReadFramebuffer(0);
1853 }
1854
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001855 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001856 {
1857 bindDrawFramebuffer(0);
1858 }
1859}
1860
1861void Context::detachRenderbuffer(GLuint renderbuffer)
1862{
Shannon Woods53a94a82014-06-24 15:20:36 -04001863 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001864}
1865
Jamie Madill57a89722013-07-02 11:57:03 -04001866void Context::detachVertexArray(GLuint vertexArray)
1867{
Jamie Madill77a72f62015-04-14 11:18:32 -04001868 // Vertex array detachment is handled by Context, because 0 is a valid
1869 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001870 // binding time.
1871
Jamie Madill57a89722013-07-02 11:57:03 -04001872 // [OpenGL ES 3.0.2] section 2.10 page 43:
1873 // If a vertex array object that is currently bound is deleted, the binding
1874 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001875 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001876 {
1877 bindVertexArray(0);
1878 }
1879}
1880
Geoff Langc8058452014-02-03 12:04:11 -05001881void Context::detachTransformFeedback(GLuint transformFeedback)
1882{
Corentin Walleza2257da2016-04-19 16:43:12 -04001883 // Transform feedback detachment is handled by Context, because 0 is a valid
1884 // transform feedback, and a pointer to it must be passed from Context to State at
1885 // binding time.
1886
1887 // The OpenGL specification doesn't mention what should happen when the currently bound
1888 // transform feedback object is deleted. Since it is a container object, we treat it like
1889 // VAOs and FBOs and set the current bound transform feedback back to 0.
1890 if (mState.removeTransformFeedbackBinding(transformFeedback))
1891 {
1892 bindTransformFeedback(0);
1893 }
Geoff Langc8058452014-02-03 12:04:11 -05001894}
1895
Jamie Madilldc356042013-07-19 16:36:57 -04001896void Context::detachSampler(GLuint sampler)
1897{
Shannon Woods53a94a82014-06-24 15:20:36 -04001898 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001899}
1900
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001901void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1902{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001903 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001904}
1905
Jamie Madille29d1672013-07-19 16:36:57 -04001906void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1907{
1908 mResourceManager->checkSamplerAllocation(sampler);
1909
1910 Sampler *samplerObject = getSampler(sampler);
1911 ASSERT(samplerObject);
1912
Geoff Lang69cce582015-09-17 13:20:36 -04001913 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001914 switch (pname)
1915 {
Geoff Lang69cce582015-09-17 13:20:36 -04001916 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1917 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1918 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1919 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1920 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1921 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1922 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1923 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1924 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1925 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1926 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001927 }
Geoff Lang69cce582015-09-17 13:20:36 -04001928 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001929}
1930
1931void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1932{
1933 mResourceManager->checkSamplerAllocation(sampler);
1934
1935 Sampler *samplerObject = getSampler(sampler);
1936 ASSERT(samplerObject);
1937
Geoff Lang69cce582015-09-17 13:20:36 -04001938 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001939 switch (pname)
1940 {
Geoff Lang69cce582015-09-17 13:20:36 -04001941 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1942 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1943 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1944 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1945 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1946 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1947 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1948 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1949 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1950 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1951 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001952 }
Geoff Lang69cce582015-09-17 13:20:36 -04001953 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001954}
1955
Jamie Madill9675b802013-07-19 16:36:59 -04001956GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1957{
1958 mResourceManager->checkSamplerAllocation(sampler);
1959
1960 Sampler *samplerObject = getSampler(sampler);
1961 ASSERT(samplerObject);
1962
Geoff Lang69cce582015-09-17 13:20:36 -04001963 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001964 switch (pname)
1965 {
Geoff Lang69cce582015-09-17 13:20:36 -04001966 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1967 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1968 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1969 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1970 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1971 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
Olli Etuaho6ad07232016-03-03 17:15:49 +02001972 case GL_TEXTURE_MIN_LOD: return iround<GLint>(samplerObject->getMinLod());
1973 case GL_TEXTURE_MAX_LOD: return iround<GLint>(samplerObject->getMaxLod());
Geoff Lang69cce582015-09-17 13:20:36 -04001974 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1975 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1976 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001977 }
Geoff Lang69cce582015-09-17 13:20:36 -04001978 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001979}
1980
1981GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1982{
1983 mResourceManager->checkSamplerAllocation(sampler);
1984
1985 Sampler *samplerObject = getSampler(sampler);
1986 ASSERT(samplerObject);
1987
Geoff Lang69cce582015-09-17 13:20:36 -04001988 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001989 switch (pname)
1990 {
Geoff Lang69cce582015-09-17 13:20:36 -04001991 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1992 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1993 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1994 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1995 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1996 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1997 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1998 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1999 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
2000 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
2001 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04002002 }
Geoff Lang69cce582015-09-17 13:20:36 -04002003 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04002004}
2005
Olli Etuahof0fee072016-03-30 15:11:58 +03002006void Context::programParameteri(GLuint program, GLenum pname, GLint value)
2007{
2008 gl::Program *programObject = getProgram(program);
2009 ASSERT(programObject != nullptr);
2010
2011 ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT);
2012 programObject->setBinaryRetrievableHint(value != GL_FALSE);
2013}
2014
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015void Context::initRendererString()
2016{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002017 std::ostringstream rendererString;
2018 rendererString << "ANGLE (";
2019 rendererString << mRenderer->getRendererDescription();
2020 rendererString << ")";
2021
Geoff Langcec35902014-04-16 10:52:36 -04002022 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002023}
2024
Geoff Langc0b9ef42014-07-02 10:02:37 -04002025const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002026{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002027 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002028}
2029
Geoff Langcec35902014-04-16 10:52:36 -04002030void Context::initExtensionStrings()
2031{
Geoff Lang493daf52014-07-03 13:38:44 -04002032 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04002033
Geoff Langc0b9ef42014-07-02 10:02:37 -04002034 std::ostringstream combinedStringStream;
2035 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2036 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002037}
2038
Geoff Langc0b9ef42014-07-02 10:02:37 -04002039const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002040{
2041 return mExtensionString;
2042}
2043
Geoff Langc0b9ef42014-07-02 10:02:37 -04002044const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002045{
2046 return mExtensionStrings[idx];
2047}
2048
2049size_t Context::getExtensionStringCount() const
2050{
2051 return mExtensionStrings.size();
2052}
2053
Olli Etuahoc3e55a42016-03-09 16:29:18 +02002054void Context::beginTransformFeedback(GLenum primitiveMode)
2055{
2056 TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback();
2057 ASSERT(transformFeedback != nullptr);
2058 ASSERT(!transformFeedback->isPaused());
2059
2060 transformFeedback->begin(primitiveMode, getState().getProgram());
2061}
2062
2063bool Context::hasActiveTransformFeedback(GLuint program) const
2064{
2065 for (auto pair : mTransformFeedbackMap)
2066 {
2067 if (pair.second != nullptr && pair.second->hasBoundProgram(program))
2068 {
2069 return true;
2070 }
2071 }
2072 return false;
2073}
2074
Geoff Lang493daf52014-07-03 13:38:44 -04002075void Context::initCaps(GLuint clientVersion)
2076{
2077 mCaps = mRenderer->getRendererCaps();
2078
2079 mExtensions = mRenderer->getRendererExtensions();
2080
Austin Kinross02df7962015-07-01 10:03:42 -07002081 mLimitations = mRenderer->getRendererLimitations();
2082
Geoff Lang493daf52014-07-03 13:38:44 -04002083 if (clientVersion < 3)
2084 {
2085 // Disable ES3+ extensions
2086 mExtensions.colorBufferFloat = false;
2087 }
2088
2089 if (clientVersion > 2)
2090 {
2091 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2092 //mExtensions.sRGB = false;
2093 }
2094
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 // Explicitly enable GL_KHR_debug
2096 mExtensions.debug = true;
2097 mExtensions.maxDebugMessageLength = 1024;
2098 mExtensions.maxDebugLoggedMessages = 1024;
2099 mExtensions.maxDebugGroupStackDepth = 1024;
2100 mExtensions.maxLabelLength = 1024;
2101
Geoff Lang301d1612014-07-09 10:34:37 -04002102 // Apply implementation limits
2103 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04002104 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2105 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2106
2107 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002108
Geoff Lang900013c2014-07-07 11:32:19 -04002109 mCaps.compressedTextureFormats.clear();
2110
Geoff Lang493daf52014-07-03 13:38:44 -04002111 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2112 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2113 {
2114 GLenum format = i->first;
2115 TextureCaps formatCaps = i->second;
2116
Geoff Lang5d601382014-07-22 15:14:06 -04002117 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002118
Geoff Lang0d8b7242015-09-09 14:56:53 -04002119 // Update the format caps based on the client version and extensions.
2120 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2121 // ES3.
2122 formatCaps.texturable =
2123 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2124 formatCaps.renderable =
2125 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2126 formatCaps.filterable =
2127 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002128
2129 // OpenGL ES does not support multisampling with integer formats
2130 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002131 {
Geoff Langd87878e2014-09-19 15:42:59 -04002132 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002133 }
Geoff Langd87878e2014-09-19 15:42:59 -04002134
2135 if (formatCaps.texturable && formatInfo.compressed)
2136 {
2137 mCaps.compressedTextureFormats.push_back(format);
2138 }
2139
2140 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002141 }
2142}
2143
Jamie Madill1b94d432015-08-07 13:23:23 -04002144void Context::syncRendererState()
2145{
2146 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002147 mRenderer->syncState(mState, dirtyBits);
2148 mState.clearDirtyBits();
2149 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002150}
2151
Jamie Madillad9f24e2016-02-12 09:27:24 -05002152void Context::syncRendererState(const State::DirtyBits &bitMask,
2153 const State::DirtyObjects &objectMask)
Jamie Madill1b94d432015-08-07 13:23:23 -04002154{
2155 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002156 mRenderer->syncState(mState, dirtyBits);
2157 mState.clearDirtyBits(dirtyBits);
2158
Jamie Madillad9f24e2016-02-12 09:27:24 -05002159 mState.syncDirtyObjects(objectMask);
Jamie Madill1b94d432015-08-07 13:23:23 -04002160}
Jamie Madillc29968b2016-01-20 11:17:23 -05002161
2162void Context::blitFramebuffer(GLint srcX0,
2163 GLint srcY0,
2164 GLint srcX1,
2165 GLint srcY1,
2166 GLint dstX0,
2167 GLint dstY0,
2168 GLint dstX1,
2169 GLint dstY1,
2170 GLbitfield mask,
2171 GLenum filter)
2172{
Jamie Madillc29968b2016-01-20 11:17:23 -05002173 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2174 ASSERT(drawFramebuffer);
2175
2176 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2177 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2178
Jamie Madillad9f24e2016-02-12 09:27:24 -05002179 syncStateForBlit();
Jamie Madillc29968b2016-01-20 11:17:23 -05002180
Jamie Madill8415b5f2016-04-26 13:41:39 -04002181 handleError(drawFramebuffer->blit(mImplementation.get(), srcArea, dstArea, mask, filter));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002182}
Jamie Madillc29968b2016-01-20 11:17:23 -05002183
2184void Context::clear(GLbitfield mask)
2185{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002186 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002187 handleError(mState.getDrawFramebuffer()->clear(mImplementation.get(), mask));
Jamie Madillc29968b2016-01-20 11:17:23 -05002188}
2189
2190void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2191{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002192 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002193 handleError(mState.getDrawFramebuffer()->clearBufferfv(mImplementation.get(), buffer,
2194 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002195}
2196
2197void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2198{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002199 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002200 handleError(mState.getDrawFramebuffer()->clearBufferuiv(mImplementation.get(), buffer,
2201 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002202}
2203
2204void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2205{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002206 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002207 handleError(mState.getDrawFramebuffer()->clearBufferiv(mImplementation.get(), buffer,
2208 drawbuffer, values));
Jamie Madillc29968b2016-01-20 11:17:23 -05002209}
2210
2211void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2212{
2213 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2214 ASSERT(framebufferObject);
2215
2216 // If a buffer is not present, the clear has no effect
2217 if (framebufferObject->getDepthbuffer() == nullptr &&
2218 framebufferObject->getStencilbuffer() == nullptr)
2219 {
2220 return;
2221 }
2222
Jamie Madillad9f24e2016-02-12 09:27:24 -05002223 syncStateForClear();
Jamie Madill8415b5f2016-04-26 13:41:39 -04002224 handleError(framebufferObject->clearBufferfi(mImplementation.get(), buffer, drawbuffer, depth,
2225 stencil));
Jamie Madillc29968b2016-01-20 11:17:23 -05002226}
2227
2228void Context::readPixels(GLint x,
2229 GLint y,
2230 GLsizei width,
2231 GLsizei height,
2232 GLenum format,
2233 GLenum type,
2234 GLvoid *pixels)
2235{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002236 syncStateForReadPixels();
Jamie Madillc29968b2016-01-20 11:17:23 -05002237
2238 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2239 ASSERT(framebufferObject);
2240
2241 Rectangle area(x, y, width, height);
Jamie Madill8415b5f2016-04-26 13:41:39 -04002242 handleError(framebufferObject->readPixels(mImplementation.get(), area, format, type, pixels));
Jamie Madillc29968b2016-01-20 11:17:23 -05002243}
2244
2245void Context::copyTexImage2D(GLenum target,
2246 GLint level,
2247 GLenum internalformat,
2248 GLint x,
2249 GLint y,
2250 GLsizei width,
2251 GLsizei height,
2252 GLint border)
2253{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002254 // Only sync the read FBO
2255 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2256
Jamie Madillc29968b2016-01-20 11:17:23 -05002257 Rectangle sourceArea(x, y, width, height);
2258
2259 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2260 Texture *texture =
2261 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002262 handleError(texture->copyImage(target, level, sourceArea, internalformat, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002263}
2264
2265void Context::copyTexSubImage2D(GLenum target,
2266 GLint level,
2267 GLint xoffset,
2268 GLint yoffset,
2269 GLint x,
2270 GLint y,
2271 GLsizei width,
2272 GLsizei height)
2273{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002274 // Only sync the read FBO
2275 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2276
Jamie Madillc29968b2016-01-20 11:17:23 -05002277 Offset destOffset(xoffset, yoffset, 0);
2278 Rectangle sourceArea(x, y, width, height);
2279
2280 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2281 Texture *texture =
2282 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002283 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002284}
2285
2286void Context::copyTexSubImage3D(GLenum target,
2287 GLint level,
2288 GLint xoffset,
2289 GLint yoffset,
2290 GLint zoffset,
2291 GLint x,
2292 GLint y,
2293 GLsizei width,
2294 GLsizei height)
2295{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002296 // Only sync the read FBO
2297 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2298
Jamie Madillc29968b2016-01-20 11:17:23 -05002299 Offset destOffset(xoffset, yoffset, zoffset);
2300 Rectangle sourceArea(x, y, width, height);
2301
2302 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2303 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002304 handleError(texture->copySubImage(target, level, destOffset, sourceArea, framebuffer));
Jamie Madillc29968b2016-01-20 11:17:23 -05002305}
2306
2307void Context::framebufferTexture2D(GLenum target,
2308 GLenum attachment,
2309 GLenum textarget,
2310 GLuint texture,
2311 GLint level)
2312{
2313 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2314 ASSERT(framebuffer);
2315
2316 if (texture != 0)
2317 {
2318 Texture *textureObj = getTexture(texture);
2319
2320 ImageIndex index = ImageIndex::MakeInvalid();
2321
2322 if (textarget == GL_TEXTURE_2D)
2323 {
2324 index = ImageIndex::Make2D(level);
2325 }
2326 else
2327 {
2328 ASSERT(IsCubeMapTextureTarget(textarget));
2329 index = ImageIndex::MakeCube(textarget, level);
2330 }
2331
2332 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2333 }
2334 else
2335 {
2336 framebuffer->resetAttachment(attachment);
2337 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002338
2339 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002340}
2341
2342void Context::framebufferRenderbuffer(GLenum target,
2343 GLenum attachment,
2344 GLenum renderbuffertarget,
2345 GLuint renderbuffer)
2346{
2347 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2348 ASSERT(framebuffer);
2349
2350 if (renderbuffer != 0)
2351 {
2352 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2353 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2354 renderbufferObject);
2355 }
2356 else
2357 {
2358 framebuffer->resetAttachment(attachment);
2359 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002360
2361 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002362}
2363
2364void Context::framebufferTextureLayer(GLenum target,
2365 GLenum attachment,
2366 GLuint texture,
2367 GLint level,
2368 GLint layer)
2369{
2370 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2371 ASSERT(framebuffer);
2372
2373 if (texture != 0)
2374 {
2375 Texture *textureObject = getTexture(texture);
2376
2377 ImageIndex index = ImageIndex::MakeInvalid();
2378
2379 if (textureObject->getTarget() == GL_TEXTURE_3D)
2380 {
2381 index = ImageIndex::Make3D(level, layer);
2382 }
2383 else
2384 {
2385 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2386 index = ImageIndex::Make2DArray(level, layer);
2387 }
2388
2389 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2390 }
2391 else
2392 {
2393 framebuffer->resetAttachment(attachment);
2394 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002395
2396 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002397}
2398
2399void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2400{
2401 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2402 ASSERT(framebuffer);
2403 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002404 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002405}
2406
2407void Context::readBuffer(GLenum mode)
2408{
2409 Framebuffer *readFBO = mState.getReadFramebuffer();
2410 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002411 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002412}
2413
2414void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2415{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002416 // Only sync the FBO
2417 mState.syncDirtyObject(target);
2418
Jamie Madillc29968b2016-01-20 11:17:23 -05002419 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2420 ASSERT(framebuffer);
2421
2422 // The specification isn't clear what should be done when the framebuffer isn't complete.
2423 // We leave it up to the framebuffer implementation to decide what to do.
Jamie Madill437fa652016-05-03 15:13:24 -04002424 handleError(framebuffer->discard(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002425}
2426
2427void Context::invalidateFramebuffer(GLenum target,
2428 GLsizei numAttachments,
2429 const GLenum *attachments)
2430{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002431 // Only sync the FBO
2432 mState.syncDirtyObject(target);
2433
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2435 ASSERT(framebuffer);
2436
Jamie Madill437fa652016-05-03 15:13:24 -04002437 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002438 {
Jamie Madill437fa652016-05-03 15:13:24 -04002439 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 }
Jamie Madill437fa652016-05-03 15:13:24 -04002441
2442 handleError(framebuffer->invalidate(numAttachments, attachments));
Jamie Madillc29968b2016-01-20 11:17:23 -05002443}
2444
2445void Context::invalidateSubFramebuffer(GLenum target,
2446 GLsizei numAttachments,
2447 const GLenum *attachments,
2448 GLint x,
2449 GLint y,
2450 GLsizei width,
2451 GLsizei height)
2452{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002453 // Only sync the FBO
2454 mState.syncDirtyObject(target);
2455
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2457 ASSERT(framebuffer);
2458
Jamie Madill437fa652016-05-03 15:13:24 -04002459 if (framebuffer->checkStatus(mData) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002460 {
Jamie Madill437fa652016-05-03 15:13:24 -04002461 return;
Jamie Madillc29968b2016-01-20 11:17:23 -05002462 }
Jamie Madill437fa652016-05-03 15:13:24 -04002463
2464 Rectangle area(x, y, width, height);
2465 handleError(framebuffer->invalidateSub(numAttachments, attachments, area));
Jamie Madillc29968b2016-01-20 11:17:23 -05002466}
2467
Jamie Madill73a84962016-02-12 09:27:23 -05002468void Context::texImage2D(GLenum target,
2469 GLint level,
2470 GLint internalformat,
2471 GLsizei width,
2472 GLsizei height,
2473 GLint border,
2474 GLenum format,
2475 GLenum type,
2476 const GLvoid *pixels)
2477{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002478 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002479
2480 Extents size(width, height, 1);
2481 Texture *texture =
2482 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002483 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2484 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002485}
2486
2487void Context::texImage3D(GLenum target,
2488 GLint level,
2489 GLint internalformat,
2490 GLsizei width,
2491 GLsizei height,
2492 GLsizei depth,
2493 GLint border,
2494 GLenum format,
2495 GLenum type,
2496 const GLvoid *pixels)
2497{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002498 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002499
2500 Extents size(width, height, depth);
2501 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002502 handleError(texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2503 format, type, reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002504}
2505
2506void Context::texSubImage2D(GLenum target,
2507 GLint level,
2508 GLint xoffset,
2509 GLint yoffset,
2510 GLsizei width,
2511 GLsizei height,
2512 GLenum format,
2513 GLenum type,
2514 const GLvoid *pixels)
2515{
2516 // Zero sized uploads are valid but no-ops
2517 if (width == 0 || height == 0)
2518 {
2519 return;
2520 }
2521
Jamie Madillad9f24e2016-02-12 09:27:24 -05002522 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002523
2524 Box area(xoffset, yoffset, 0, width, height, 1);
2525 Texture *texture =
2526 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002527 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2528 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002529}
2530
2531void Context::texSubImage3D(GLenum target,
2532 GLint level,
2533 GLint xoffset,
2534 GLint yoffset,
2535 GLint zoffset,
2536 GLsizei width,
2537 GLsizei height,
2538 GLsizei depth,
2539 GLenum format,
2540 GLenum type,
2541 const GLvoid *pixels)
2542{
2543 // Zero sized uploads are valid but no-ops
2544 if (width == 0 || height == 0 || depth == 0)
2545 {
2546 return;
2547 }
2548
Jamie Madillad9f24e2016-02-12 09:27:24 -05002549 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002550
2551 Box area(xoffset, yoffset, zoffset, width, height, depth);
2552 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002553 handleError(texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2554 reinterpret_cast<const uint8_t *>(pixels)));
Jamie Madill73a84962016-02-12 09:27:23 -05002555}
2556
2557void Context::compressedTexImage2D(GLenum target,
2558 GLint level,
2559 GLenum internalformat,
2560 GLsizei width,
2561 GLsizei height,
2562 GLint border,
2563 GLsizei imageSize,
2564 const GLvoid *data)
2565{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002566 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002567
2568 Extents size(width, height, 1);
2569 Texture *texture =
2570 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002571 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2572 size, imageSize,
2573 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002574}
2575
2576void Context::compressedTexImage3D(GLenum target,
2577 GLint level,
2578 GLenum internalformat,
2579 GLsizei width,
2580 GLsizei height,
2581 GLsizei depth,
2582 GLint border,
2583 GLsizei imageSize,
2584 const GLvoid *data)
2585{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002586 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002587
2588 Extents size(width, height, depth);
2589 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002590 handleError(texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat,
2591 size, imageSize,
2592 reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002593}
2594
2595void Context::compressedTexSubImage2D(GLenum target,
2596 GLint level,
2597 GLint xoffset,
2598 GLint yoffset,
2599 GLsizei width,
2600 GLsizei height,
2601 GLenum format,
2602 GLsizei imageSize,
2603 const GLvoid *data)
2604{
Jamie Madillad9f24e2016-02-12 09:27:24 -05002605 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002606
2607 Box area(xoffset, yoffset, 0, width, height, 1);
2608 Texture *texture =
2609 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Jamie Madill437fa652016-05-03 15:13:24 -04002610 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2611 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002612}
2613
2614void Context::compressedTexSubImage3D(GLenum target,
2615 GLint level,
2616 GLint xoffset,
2617 GLint yoffset,
2618 GLint zoffset,
2619 GLsizei width,
2620 GLsizei height,
2621 GLsizei depth,
2622 GLenum format,
2623 GLsizei imageSize,
2624 const GLvoid *data)
2625{
2626 // Zero sized uploads are valid but no-ops
2627 if (width == 0 || height == 0)
2628 {
2629 return;
2630 }
2631
Jamie Madillad9f24e2016-02-12 09:27:24 -05002632 syncStateForTexImage();
Jamie Madill73a84962016-02-12 09:27:23 -05002633
2634 Box area(xoffset, yoffset, zoffset, width, height, depth);
2635 Texture *texture = getTargetTexture(target);
Jamie Madill437fa652016-05-03 15:13:24 -04002636 handleError(texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2637 imageSize, reinterpret_cast<const uint8_t *>(data)));
Jamie Madill73a84962016-02-12 09:27:23 -05002638}
2639
Olli Etuaho4f667482016-03-30 15:56:35 +03002640void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params)
2641{
2642 Buffer *buffer = getState().getTargetBuffer(target);
2643 ASSERT(buffer);
2644
2645 if (!buffer->isMapped())
2646 {
2647 *params = nullptr;
2648 }
2649 else
2650 {
2651 *params = buffer->getMapPointer();
2652 }
2653}
2654
2655GLvoid *Context::mapBuffer(GLenum target, GLenum access)
2656{
2657 Buffer *buffer = getState().getTargetBuffer(target);
2658 ASSERT(buffer);
2659
2660 Error error = buffer->map(access);
2661 if (error.isError())
2662 {
Jamie Madill437fa652016-05-03 15:13:24 -04002663 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002664 return nullptr;
2665 }
2666
2667 return buffer->getMapPointer();
2668}
2669
2670GLboolean Context::unmapBuffer(GLenum target)
2671{
2672 Buffer *buffer = getState().getTargetBuffer(target);
2673 ASSERT(buffer);
2674
2675 GLboolean result;
2676 Error error = buffer->unmap(&result);
2677 if (error.isError())
2678 {
Jamie Madill437fa652016-05-03 15:13:24 -04002679 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002680 return GL_FALSE;
2681 }
2682
2683 return result;
2684}
2685
2686GLvoid *Context::mapBufferRange(GLenum target,
2687 GLintptr offset,
2688 GLsizeiptr length,
2689 GLbitfield access)
2690{
2691 Buffer *buffer = getState().getTargetBuffer(target);
2692 ASSERT(buffer);
2693
2694 Error error = buffer->mapRange(offset, length, access);
2695 if (error.isError())
2696 {
Jamie Madill437fa652016-05-03 15:13:24 -04002697 handleError(error);
Olli Etuaho4f667482016-03-30 15:56:35 +03002698 return nullptr;
2699 }
2700
2701 return buffer->getMapPointer();
2702}
2703
2704void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/)
2705{
2706 // We do not currently support a non-trivial implementation of FlushMappedBufferRange
2707}
2708
Jamie Madillad9f24e2016-02-12 09:27:24 -05002709void Context::syncStateForReadPixels()
2710{
2711 syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
2712}
2713
2714void Context::syncStateForTexImage()
2715{
2716 syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
2717}
2718
2719void Context::syncStateForClear()
2720{
2721 syncRendererState(mClearDirtyBits, mClearDirtyObjects);
2722}
2723
2724void Context::syncStateForBlit()
2725{
2726 syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
2727}
2728
Jamie Madillc29968b2016-01-20 11:17:23 -05002729} // namespace gl