blob: 394502e327f3a489769ed1b8188b6367bbeee7c0 [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"
34#include "libANGLE/renderer/Renderer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000035
Geoff Langf6db0982015-08-25 13:04:00 -040036namespace
37{
38
Ian Ewell3ffd78b2016-01-22 16:09:42 -050039template <typename T>
40gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
41{
42 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
43 ASSERT(queryObject != nullptr);
44
45 switch (pname)
46 {
47 case GL_QUERY_RESULT_EXT:
48 return queryObject->getResult(params);
49 case GL_QUERY_RESULT_AVAILABLE_EXT:
50 {
51 bool available;
52 gl::Error error = queryObject->isResultAvailable(&available);
53 if (!error.isError())
54 {
55 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
56 }
57 return error;
58 }
59 default:
60 UNREACHABLE();
61 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
62 }
63}
64
Geoff Langf6db0982015-08-25 13:04:00 -040065void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
66{
Geoff Lang1a683462015-09-29 15:09:59 -040067 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040068 {
69 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
70 tfBufferIndex++)
71 {
72 const OffsetBindingPointer<gl::Buffer> &buffer =
73 transformFeedback->getIndexedBuffer(tfBufferIndex);
74 if (buffer.get() != nullptr)
75 {
76 buffer->onTransformFeedback();
77 }
78 }
79 }
80}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050081
82// Attribute map queries.
83EGLint GetClientVersion(const egl::AttributeMap &attribs)
84{
85 return attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
86}
87
88GLenum GetResetStrategy(const egl::AttributeMap &attribs)
89{
90 EGLenum attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
91 EGL_NO_RESET_NOTIFICATION_EXT);
92 switch (attrib)
93 {
94 case EGL_NO_RESET_NOTIFICATION:
95 return GL_NO_RESET_NOTIFICATION_EXT;
96 case EGL_LOSE_CONTEXT_ON_RESET:
97 return GL_LOSE_CONTEXT_ON_RESET_EXT;
98 default:
99 UNREACHABLE();
100 return GL_NONE;
101 }
102}
103
104bool GetRobustAccess(const egl::AttributeMap &attribs)
105{
106 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
107}
108
109bool GetDebug(const egl::AttributeMap &attribs)
110{
111 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
112}
113
114bool GetNoError(const egl::AttributeMap &attribs)
115{
116 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
117}
118
Geoff Langf6db0982015-08-25 13:04:00 -0400119} // anonymous namespace
120
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000121namespace gl
122{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000123
Corentin Wallez51706ea2015-08-07 14:39:22 -0400124Context::Context(const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400125 const Context *shareContext,
126 rx::Renderer *renderer,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500127 const egl::AttributeMap &attribs)
128 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500129 mState,
130 mCaps,
131 mTextureCaps,
132 mExtensions,
133 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500134 mLimitations,
135 GetNoError(attribs)),
136 mCompiler(nullptr),
Jamie Madillf25855c2015-11-03 11:06:18 -0500137 mRenderer(renderer),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400139 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140 mClientType(EGL_OPENGL_ES_API),
141 mHasBeenCurrent(false),
142 mContextLost(false),
143 mResetStatus(GL_NO_ERROR),
144 mResetStrategy(GetResetStrategy(attribs)),
145 mRobustAccess(GetRobustAccess(attribs)),
146 mCurrentSurface(nullptr),
147 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000148{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400152
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100154
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400156
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000157 if (shareContext != NULL)
158 {
159 mResourceManager = shareContext->mResourceManager;
160 mResourceManager->addRef();
161 }
162 else
163 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000164 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000165 }
166
Jamie Madillc185cb82015-04-28 12:39:08 -0400167 mData.resourceManager = mResourceManager;
168
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000169 // [OpenGL ES 2.0.24] section 3.7 page 83:
170 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
171 // and cube map texture state vectors respectively associated with them.
172 // In order that access to these initial textures not be lost, they are treated as texture
173 // objects all of whose names are 0.
174
Geoff Lang691e58c2014-12-19 17:03:25 -0500175 Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500176 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500177
Geoff Lang691e58c2014-12-19 17:03:25 -0500178 Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500179 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400180
181 if (mClientVersion >= 3)
182 {
183 // TODO: These could also be enabled via extension
Geoff Lang691e58c2014-12-19 17:03:25 -0500184 Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500185 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400186
Geoff Lang691e58c2014-12-19 17:03:25 -0500187 Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500188 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400189 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000190
Jamie Madille6382c32014-11-07 15:05:26 -0500191 mState.initializeZeroTextures(mZeroTextures);
192
Jamie Madill57a89722013-07-02 11:57:03 -0400193 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000194 bindArrayBuffer(0);
195 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400196
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000197 bindRenderbuffer(0);
198
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000199 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400200 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000201 {
202 bindIndexedUniformBuffer(0, i, 0, -1);
203 }
204
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000205 bindCopyReadBuffer(0);
206 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000207 bindPixelPackBuffer(0);
208 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000209
Geoff Lang1a683462015-09-29 15:09:59 -0400210 if (mClientVersion >= 3)
211 {
212 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
213 // In the initial state, a default transform feedback object is bound and treated as
214 // a transform feedback object with a name of zero. That object is bound any time
215 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400216 bindTransformFeedback(0);
217 }
Geoff Langc8058452014-02-03 12:04:11 -0500218
Jamie Madill83f349e2015-09-23 09:50:36 -0400219 mCompiler = new Compiler(mRenderer, getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000220}
221
222Context::~Context()
223{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500224 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000225
Corentin Wallez37c39792015-08-20 14:19:46 -0400226 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000227 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400228 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400229 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400230 {
231 SafeDelete(framebuffer.second);
232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233 }
234
Corentin Wallez80b24112015-08-25 16:41:57 -0400235 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000236 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400237 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000238 }
239
Corentin Wallez80b24112015-08-25 16:41:57 -0400240 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000241 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400242 if (query.second != nullptr)
243 {
244 query.second->release();
245 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000246 }
247
Corentin Wallez80b24112015-08-25 16:41:57 -0400248 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400249 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400250 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400251 }
252
Corentin Wallez80b24112015-08-25 16:41:57 -0400253 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500254 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500255 if (transformFeedback.second != nullptr)
256 {
257 transformFeedback.second->release();
258 }
Geoff Langc8058452014-02-03 12:04:11 -0500259 }
260
Jamie Madilldedd7b92014-11-05 16:30:36 -0500261 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400262 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500263 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400264 }
265 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000266
Corentin Wallez51706ea2015-08-07 14:39:22 -0400267 if (mCurrentSurface != nullptr)
268 {
269 releaseSurface();
270 }
271
Jamie Madill1e9ae072014-11-06 15:27:21 -0500272 if (mResourceManager)
273 {
274 mResourceManager->release();
275 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500276
277 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278}
279
daniel@transgaming.comad629872012-11-28 19:32:06 +0000280void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281{
Jamie Madill77a72f62015-04-14 11:18:32 -0400282 ASSERT(surface != nullptr);
283
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 if (!mHasBeenCurrent)
285 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400287 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
290 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291
292 mHasBeenCurrent = true;
293 }
294
Jamie Madill1b94d432015-08-07 13:23:23 -0400295 // TODO(jmadill): Rework this when we support ContextImpl
296 mState.setAllDirtyBits();
297
Corentin Wallez51706ea2015-08-07 14:39:22 -0400298 if (mCurrentSurface)
299 {
300 releaseSurface();
301 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000302 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400303 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000304
Corentin Wallez37c39792015-08-20 14:19:46 -0400305 // Update default framebuffer, the binding of the previous default
306 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400307 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400308 Framebuffer *newDefault = surface->getDefaultFramebuffer();
309 if (mState.getReadFramebuffer() == nullptr)
310 {
311 mState.setReadFramebufferBinding(newDefault);
312 }
313 if (mState.getDrawFramebuffer() == nullptr)
314 {
315 mState.setDrawFramebufferBinding(newDefault);
316 }
317 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400318 }
Ian Ewell292f0052016-02-04 10:37:32 -0500319
320 // Notify the renderer of a context switch
321 mRenderer->onMakeCurrent(getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000322}
323
Jamie Madill77a72f62015-04-14 11:18:32 -0400324void Context::releaseSurface()
325{
Corentin Wallez37c39792015-08-20 14:19:46 -0400326 ASSERT(mCurrentSurface != nullptr);
327
328 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400329 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400330 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
331 if (mState.getReadFramebuffer() == currentDefault)
332 {
333 mState.setReadFramebufferBinding(nullptr);
334 }
335 if (mState.getDrawFramebuffer() == currentDefault)
336 {
337 mState.setDrawFramebufferBinding(nullptr);
338 }
339 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400340 }
341
Corentin Wallez51706ea2015-08-07 14:39:22 -0400342 mCurrentSurface->setIsCurrent(false);
343 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400344}
345
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000346// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000347void Context::markContextLost()
348{
349 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
350 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
351 mContextLost = true;
352}
353
354bool Context::isContextLost()
355{
356 return mContextLost;
357}
358
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000359GLuint Context::createBuffer()
360{
361 return mResourceManager->createBuffer();
362}
363
364GLuint Context::createProgram()
365{
366 return mResourceManager->createProgram();
367}
368
369GLuint Context::createShader(GLenum type)
370{
Jamie Madill006cbc52015-09-23 16:47:54 -0400371 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000372}
373
374GLuint Context::createTexture()
375{
376 return mResourceManager->createTexture();
377}
378
379GLuint Context::createRenderbuffer()
380{
381 return mResourceManager->createRenderbuffer();
382}
383
Geoff Lang882033e2014-09-30 11:26:07 -0400384GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400385{
386 GLuint handle = mResourceManager->createFenceSync();
387
Cooper Partind8e62a32015-01-29 15:21:25 -0800388 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400389}
390
Jamie Madill57a89722013-07-02 11:57:03 -0400391GLuint Context::createVertexArray()
392{
Geoff Lang36167ab2015-12-07 10:27:14 -0500393 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
394 mVertexArrayMap[vertexArray] = nullptr;
395 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400396}
397
Jamie Madilldc356042013-07-19 16:36:57 -0400398GLuint Context::createSampler()
399{
400 return mResourceManager->createSampler();
401}
402
Geoff Langc8058452014-02-03 12:04:11 -0500403GLuint Context::createTransformFeedback()
404{
Geoff Lang36167ab2015-12-07 10:27:14 -0500405 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
406 mTransformFeedbackMap[transformFeedback] = nullptr;
407 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500408}
409
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000410// Returns an unused framebuffer name
411GLuint Context::createFramebuffer()
412{
413 GLuint handle = mFramebufferHandleAllocator.allocate();
414
415 mFramebufferMap[handle] = NULL;
416
417 return handle;
418}
419
Jamie Madill33dc8432013-07-26 11:55:05 -0400420GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000421{
Jamie Madill33dc8432013-07-26 11:55:05 -0400422 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000423
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700424 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000425
426 return handle;
427}
428
429// Returns an unused query name
430GLuint Context::createQuery()
431{
432 GLuint handle = mQueryHandleAllocator.allocate();
433
434 mQueryMap[handle] = NULL;
435
436 return handle;
437}
438
439void Context::deleteBuffer(GLuint buffer)
440{
441 if (mResourceManager->getBuffer(buffer))
442 {
443 detachBuffer(buffer);
444 }
Jamie Madill893ab082014-05-16 16:56:10 -0400445
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000446 mResourceManager->deleteBuffer(buffer);
447}
448
449void Context::deleteShader(GLuint shader)
450{
451 mResourceManager->deleteShader(shader);
452}
453
454void Context::deleteProgram(GLuint program)
455{
456 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000457}
458
459void Context::deleteTexture(GLuint texture)
460{
461 if (mResourceManager->getTexture(texture))
462 {
463 detachTexture(texture);
464 }
465
466 mResourceManager->deleteTexture(texture);
467}
468
469void Context::deleteRenderbuffer(GLuint renderbuffer)
470{
471 if (mResourceManager->getRenderbuffer(renderbuffer))
472 {
473 detachRenderbuffer(renderbuffer);
474 }
Jamie Madill893ab082014-05-16 16:56:10 -0400475
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000476 mResourceManager->deleteRenderbuffer(renderbuffer);
477}
478
Jamie Madillcd055f82013-07-26 11:55:15 -0400479void Context::deleteFenceSync(GLsync fenceSync)
480{
481 // The spec specifies the underlying Fence object is not deleted until all current
482 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
483 // and since our API is currently designed for being called from a single thread, we can delete
484 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700485 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400486}
487
Jamie Madill57a89722013-07-02 11:57:03 -0400488void Context::deleteVertexArray(GLuint vertexArray)
489{
Geoff Lang36167ab2015-12-07 10:27:14 -0500490 auto iter = mVertexArrayMap.find(vertexArray);
491 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000492 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500493 VertexArray *vertexArrayObject = iter->second;
494 if (vertexArrayObject != nullptr)
495 {
496 detachVertexArray(vertexArray);
497 delete vertexArrayObject;
498 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000499
Geoff Lang36167ab2015-12-07 10:27:14 -0500500 mVertexArrayMap.erase(iter);
501 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400502 }
503}
504
Jamie Madilldc356042013-07-19 16:36:57 -0400505void Context::deleteSampler(GLuint sampler)
506{
507 if (mResourceManager->getSampler(sampler))
508 {
509 detachSampler(sampler);
510 }
511
512 mResourceManager->deleteSampler(sampler);
513}
514
Geoff Langc8058452014-02-03 12:04:11 -0500515void Context::deleteTransformFeedback(GLuint transformFeedback)
516{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500517 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500518 if (iter != mTransformFeedbackMap.end())
519 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500520 TransformFeedback *transformFeedbackObject = iter->second;
521 if (transformFeedbackObject != nullptr)
522 {
523 detachTransformFeedback(transformFeedback);
524 transformFeedbackObject->release();
525 }
526
Geoff Lang50b3fe82015-12-08 14:49:12 +0000527 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500528 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500529 }
530}
531
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000532void Context::deleteFramebuffer(GLuint framebuffer)
533{
534 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
535
536 if (framebufferObject != mFramebufferMap.end())
537 {
538 detachFramebuffer(framebuffer);
539
540 mFramebufferHandleAllocator.release(framebufferObject->first);
541 delete framebufferObject->second;
542 mFramebufferMap.erase(framebufferObject);
543 }
544}
545
Jamie Madill33dc8432013-07-26 11:55:05 -0400546void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000547{
Jamie Madill33dc8432013-07-26 11:55:05 -0400548 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000549
Jamie Madill33dc8432013-07-26 11:55:05 -0400550 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000551 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400552 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000553 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400554 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000555 }
556}
557
558void Context::deleteQuery(GLuint query)
559{
560 QueryMap::iterator queryObject = mQueryMap.find(query);
561 if (queryObject != mQueryMap.end())
562 {
563 mQueryHandleAllocator.release(queryObject->first);
564 if (queryObject->second)
565 {
566 queryObject->second->release();
567 }
568 mQueryMap.erase(queryObject);
569 }
570}
571
Geoff Lang70d0f492015-12-10 17:45:46 -0500572Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000573{
574 return mResourceManager->getBuffer(handle);
575}
576
Geoff Lang48dcae72014-02-05 16:28:24 -0500577Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000578{
579 return mResourceManager->getShader(handle);
580}
581
Geoff Lang48dcae72014-02-05 16:28:24 -0500582Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000583{
584 return mResourceManager->getProgram(handle);
585}
586
Jamie Madill570f7c82014-07-03 10:38:54 -0400587Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000588{
589 return mResourceManager->getTexture(handle);
590}
591
Geoff Lang70d0f492015-12-10 17:45:46 -0500592Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000593{
594 return mResourceManager->getRenderbuffer(handle);
595}
596
Jamie Madillcd055f82013-07-26 11:55:15 -0400597FenceSync *Context::getFenceSync(GLsync handle) const
598{
Minmin Gong794e0002015-04-07 18:31:54 -0700599 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400600}
601
Jamie Madill57a89722013-07-02 11:57:03 -0400602VertexArray *Context::getVertexArray(GLuint handle) const
603{
604 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500605 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400606}
607
Jamie Madilldc356042013-07-19 16:36:57 -0400608Sampler *Context::getSampler(GLuint handle) const
609{
610 return mResourceManager->getSampler(handle);
611}
612
Geoff Langc8058452014-02-03 12:04:11 -0500613TransformFeedback *Context::getTransformFeedback(GLuint handle) const
614{
Geoff Lang36167ab2015-12-07 10:27:14 -0500615 auto iter = mTransformFeedbackMap.find(handle);
616 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500617}
618
Geoff Lang70d0f492015-12-10 17:45:46 -0500619LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
620{
621 switch (identifier)
622 {
623 case GL_BUFFER:
624 return getBuffer(name);
625 case GL_SHADER:
626 return getShader(name);
627 case GL_PROGRAM:
628 return getProgram(name);
629 case GL_VERTEX_ARRAY:
630 return getVertexArray(name);
631 case GL_QUERY:
632 return getQuery(name);
633 case GL_TRANSFORM_FEEDBACK:
634 return getTransformFeedback(name);
635 case GL_SAMPLER:
636 return getSampler(name);
637 case GL_TEXTURE:
638 return getTexture(name);
639 case GL_RENDERBUFFER:
640 return getRenderbuffer(name);
641 case GL_FRAMEBUFFER:
642 return getFramebuffer(name);
643 default:
644 UNREACHABLE();
645 return nullptr;
646 }
647}
648
649LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
650{
651 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
652}
653
Jamie Madilldc356042013-07-19 16:36:57 -0400654bool Context::isSampler(GLuint samplerName) const
655{
656 return mResourceManager->isSampler(samplerName);
657}
658
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000659void Context::bindArrayBuffer(unsigned int buffer)
660{
661 mResourceManager->checkBufferAllocation(buffer);
662
Shannon Woods53a94a82014-06-24 15:20:36 -0400663 mState.setArrayBufferBinding(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000664}
665
666void Context::bindElementArrayBuffer(unsigned int buffer)
667{
668 mResourceManager->checkBufferAllocation(buffer);
669
Shannon Woods53a94a82014-06-24 15:20:36 -0400670 mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671}
672
Jamie Madilldedd7b92014-11-05 16:30:36 -0500673void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000674{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500675 Texture *texture = NULL;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000676
Jamie Madilldedd7b92014-11-05 16:30:36 -0500677 if (handle == 0)
678 {
679 texture = mZeroTextures[target].get();
680 }
681 else
682 {
683 mResourceManager->checkTextureAllocation(handle, target);
684 texture = getTexture(handle);
685 }
686
687 ASSERT(texture);
688
689 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000690}
691
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500692void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000693{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500694 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
695 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000696}
697
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500698void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000699{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500700 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
701 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000702}
703
704void Context::bindRenderbuffer(GLuint renderbuffer)
705{
706 mResourceManager->checkRenderbufferAllocation(renderbuffer);
707
Shannon Woods53a94a82014-06-24 15:20:36 -0400708 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000709}
710
Jamie Madill57a89722013-07-02 11:57:03 -0400711void Context::bindVertexArray(GLuint vertexArray)
712{
Geoff Lang36167ab2015-12-07 10:27:14 -0500713 checkVertexArrayAllocation(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400714
Shannon Woods53a94a82014-06-24 15:20:36 -0400715 mState.setVertexArrayBinding(getVertexArray(vertexArray));
Jamie Madill57a89722013-07-02 11:57:03 -0400716}
717
Jamie Madilldc356042013-07-19 16:36:57 -0400718void Context::bindSampler(GLuint textureUnit, GLuint sampler)
719{
Geoff Lang76b10c92014-09-05 16:28:14 -0400720 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madilldc356042013-07-19 16:36:57 -0400721 mResourceManager->checkSamplerAllocation(sampler);
722
Shannon Woods53a94a82014-06-24 15:20:36 -0400723 mState.setSamplerBinding(textureUnit, getSampler(sampler));
Jamie Madilldc356042013-07-19 16:36:57 -0400724}
725
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000726void Context::bindGenericUniformBuffer(GLuint buffer)
727{
728 mResourceManager->checkBufferAllocation(buffer);
729
Shannon Woods53a94a82014-06-24 15:20:36 -0400730 mState.setGenericUniformBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000731}
732
733void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000734{
735 mResourceManager->checkBufferAllocation(buffer);
736
Shannon Woods53a94a82014-06-24 15:20:36 -0400737 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000738}
739
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000740void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
741{
742 mResourceManager->checkBufferAllocation(buffer);
743
Geoff Lang045536b2015-03-27 15:17:18 -0400744 mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000745}
746
747void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000748{
749 mResourceManager->checkBufferAllocation(buffer);
750
Geoff Lang045536b2015-03-27 15:17:18 -0400751 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000752}
753
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000754void Context::bindCopyReadBuffer(GLuint buffer)
755{
756 mResourceManager->checkBufferAllocation(buffer);
757
Shannon Woods53a94a82014-06-24 15:20:36 -0400758 mState.setCopyReadBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000759}
760
761void Context::bindCopyWriteBuffer(GLuint buffer)
762{
763 mResourceManager->checkBufferAllocation(buffer);
764
Shannon Woods53a94a82014-06-24 15:20:36 -0400765 mState.setCopyWriteBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000766}
767
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000768void Context::bindPixelPackBuffer(GLuint buffer)
769{
770 mResourceManager->checkBufferAllocation(buffer);
771
Shannon Woods53a94a82014-06-24 15:20:36 -0400772 mState.setPixelPackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000773}
774
775void Context::bindPixelUnpackBuffer(GLuint buffer)
776{
777 mResourceManager->checkBufferAllocation(buffer);
778
Shannon Woods53a94a82014-06-24 15:20:36 -0400779 mState.setPixelUnpackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000780}
781
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782void Context::useProgram(GLuint program)
783{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500784 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000785}
786
Geoff Langc8058452014-02-03 12:04:11 -0500787void Context::bindTransformFeedback(GLuint transformFeedback)
788{
Geoff Lang36167ab2015-12-07 10:27:14 -0500789 checkTransformFeedbackAllocation(transformFeedback);
790
Shannon Woods53a94a82014-06-24 15:20:36 -0400791 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
Geoff Langc8058452014-02-03 12:04:11 -0500792}
793
Geoff Lang5aad9672014-09-08 11:10:42 -0400794Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400797 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000798
Geoff Lang5aad9672014-09-08 11:10:42 -0400799 // begin query
800 Error error = queryObject->begin();
801 if (error.isError())
802 {
803 return error;
804 }
805
806 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400807 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000808
Geoff Lang5aad9672014-09-08 11:10:42 -0400809 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810}
811
Geoff Lang5aad9672014-09-08 11:10:42 -0400812Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813{
Shannon Woods53a94a82014-06-24 15:20:36 -0400814 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400815 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816
Geoff Lang5aad9672014-09-08 11:10:42 -0400817 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818
Geoff Lang5aad9672014-09-08 11:10:42 -0400819 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400820 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400821
822 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823}
824
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500825Error Context::queryCounter(GLuint id, GLenum target)
826{
827 ASSERT(target == GL_TIMESTAMP_EXT);
828
829 Query *queryObject = getQuery(id, true, target);
830 ASSERT(queryObject);
831
832 return queryObject->queryCounter();
833}
834
835void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
836{
837 switch (pname)
838 {
839 case GL_CURRENT_QUERY_EXT:
840 params[0] = getState().getActiveQueryId(target);
841 break;
842 case GL_QUERY_COUNTER_BITS_EXT:
843 switch (target)
844 {
845 case GL_TIME_ELAPSED_EXT:
846 params[0] = getExtensions().queryCounterBitsTimeElapsed;
847 break;
848 case GL_TIMESTAMP_EXT:
849 params[0] = getExtensions().queryCounterBitsTimestamp;
850 break;
851 default:
852 UNREACHABLE();
853 params[0] = 0;
854 break;
855 }
856 break;
857 default:
858 UNREACHABLE();
859 return;
860 }
861}
862
863Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
864{
865 return GetQueryObjectParameter(this, id, pname, params);
866}
867
868Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
869{
870 return GetQueryObjectParameter(this, id, pname, params);
871}
872
873Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
874{
875 return GetQueryObjectParameter(this, id, pname, params);
876}
877
878Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
879{
880 return GetQueryObjectParameter(this, id, pname, params);
881}
882
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500883Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500885 auto framebufferIt = mFramebufferMap.find(handle);
886 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000887}
888
Jamie Madill33dc8432013-07-26 11:55:05 -0400889FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000890{
Jamie Madill33dc8432013-07-26 11:55:05 -0400891 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000892
Jamie Madill33dc8432013-07-26 11:55:05 -0400893 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000894 {
895 return NULL;
896 }
897 else
898 {
899 return fence->second;
900 }
901}
902
903Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
904{
905 QueryMap::iterator query = mQueryMap.find(handle);
906
907 if (query == mQueryMap.end())
908 {
909 return NULL;
910 }
911 else
912 {
913 if (!query->second && create)
914 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700915 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000916 query->second->addRef();
917 }
918 return query->second;
919 }
920}
921
Geoff Lang70d0f492015-12-10 17:45:46 -0500922Query *Context::getQuery(GLuint handle) const
923{
924 auto iter = mQueryMap.find(handle);
925 return (iter != mQueryMap.end()) ? iter->second : nullptr;
926}
927
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500928Texture *Context::getTargetTexture(GLenum target) const
929{
Geoff Lang691e58c2014-12-19 17:03:25 -0500930 ASSERT(ValidTextureTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500931 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000932}
933
Geoff Lang76b10c92014-09-05 16:28:14 -0400934Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000935{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500936 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000937}
938
Geoff Lang492a7e42014-11-05 13:27:06 -0500939Compiler *Context::getCompiler() const
940{
941 return mCompiler;
942}
943
Jamie Madill893ab082014-05-16 16:56:10 -0400944void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000945{
946 switch (pname)
947 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000948 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000949 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400951 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400952 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000953 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954}
955
Jamie Madill893ab082014-05-16 16:56:10 -0400956void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957{
Shannon Woods53a94a82014-06-24 15:20:36 -0400958 // Queries about context capabilities and maximums are answered by Context.
959 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000960 switch (pname)
961 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400963 params[0] = mCaps.minAliasedLineWidth;
964 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000965 break;
966 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400967 params[0] = mCaps.minAliasedPointSize;
968 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000969 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000970 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400971 ASSERT(mExtensions.textureFilterAnisotropic);
972 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000973 break;
Geoff Lange6d4e122015-06-29 13:33:55 -0400974 case GL_MAX_TEXTURE_LOD_BIAS:
975 *params = mCaps.maxLODBias;
976 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400978 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400979 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000980 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981}
982
Jamie Madill893ab082014-05-16 16:56:10 -0400983void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000984{
Shannon Woods53a94a82014-06-24 15:20:36 -0400985 // Queries about context capabilities and maximums are answered by Context.
986 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +0000987
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000988 switch (pname)
989 {
Geoff Lang301d1612014-07-09 10:34:37 -0400990 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
991 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
992 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -0400993 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
994 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
995 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -0400996 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
997 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
998 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -0400999 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001000 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1001 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1002 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001003 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001004 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001005 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1006 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1007 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1008 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001009 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1010 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001011 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1012 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001013 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001014 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1015 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1016 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1017 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001018 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1019 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001020 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1021 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001022 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1023 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1024 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001025 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1026 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1027 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001028 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001029 case GL_MAX_VIEWPORT_DIMS:
1030 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001031 params[0] = mCaps.maxViewportWidth;
1032 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001033 }
1034 break;
1035 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001036 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001037 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001038 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1039 *params = mResetStrategy;
1040 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001041 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001042 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001043 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001044 case GL_SHADER_BINARY_FORMATS:
1045 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1046 break;
1047 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001048 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001049 break;
1050 case GL_PROGRAM_BINARY_FORMATS:
1051 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001052 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001053 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001054 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001055 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001056
1057 // GL_KHR_debug
1058 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1059 *params = mExtensions.maxDebugMessageLength;
1060 break;
1061 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1062 *params = mExtensions.maxDebugLoggedMessages;
1063 break;
1064 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1065 *params = mExtensions.maxDebugGroupStackDepth;
1066 break;
1067 case GL_MAX_LABEL_LENGTH:
1068 *params = mExtensions.maxLabelLength;
1069 break;
1070
Ian Ewell53f59f42016-01-28 17:36:55 -05001071 // GL_EXT_disjoint_timer_query
1072 case GL_GPU_DISJOINT_EXT:
1073 *params = mRenderer->getGPUDisjoint();
1074 break;
1075
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001077 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001078 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001079 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001080}
1081
Jamie Madill893ab082014-05-16 16:56:10 -04001082void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001083{
Shannon Woods53a94a82014-06-24 15:20:36 -04001084 // Queries about context capabilities and maximums are answered by Context.
1085 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001086 switch (pname)
1087 {
1088 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001089 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001090 break;
1091 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001092 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001093 break;
1094 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001095 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001096 break;
1097 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001098 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001099 break;
1100 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001101 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001102 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001103
1104 // GL_EXT_disjoint_timer_query
1105 case GL_TIMESTAMP_EXT:
1106 *params = mRenderer->getTimestamp();
1107 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001108 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001109 UNREACHABLE();
1110 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001111 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001112}
1113
Geoff Lang70d0f492015-12-10 17:45:46 -05001114void Context::getPointerv(GLenum pname, void **params) const
1115{
1116 mState.getPointerv(pname, params);
1117}
1118
Shannon Woods1b2fb852013-08-19 14:28:48 -04001119bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1120{
Shannon Woods53a94a82014-06-24 15:20:36 -04001121 // Queries about context capabilities and maximums are answered by Context.
1122 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001123 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001124 // mere passthrough.
1125 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001126}
1127
1128bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1129{
Shannon Woods53a94a82014-06-24 15:20:36 -04001130 // Queries about context capabilities and maximums are answered by Context.
1131 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001132 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001133 // mere passthrough.
1134 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001135}
1136
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001137bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1138{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001139 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1140 {
1141 *type = GL_INT;
1142 *numParams = 1;
1143 return true;
1144 }
1145
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001146 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1147 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1148 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001149 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001150 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1151 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1152 // application.
1153 switch (pname)
1154 {
1155 case GL_COMPRESSED_TEXTURE_FORMATS:
1156 {
1157 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001158 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001159 }
1160 return true;
1161 case GL_PROGRAM_BINARY_FORMATS_OES:
1162 {
1163 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001164 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001165 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001166 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 case GL_SHADER_BINARY_FORMATS:
1168 {
1169 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001170 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001172 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001173
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174 case GL_MAX_VERTEX_ATTRIBS:
1175 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1176 case GL_MAX_VARYING_VECTORS:
1177 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1178 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1179 case GL_MAX_TEXTURE_IMAGE_UNITS:
1180 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1181 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001182 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001183 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001184 case GL_NUM_SHADER_BINARY_FORMATS:
1185 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1186 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001187 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1188 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1189 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001190 case GL_RENDERBUFFER_BINDING:
1191 case GL_CURRENT_PROGRAM:
1192 case GL_PACK_ALIGNMENT:
1193 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1194 case GL_UNPACK_ALIGNMENT:
1195 case GL_GENERATE_MIPMAP_HINT:
1196 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1197 case GL_RED_BITS:
1198 case GL_GREEN_BITS:
1199 case GL_BLUE_BITS:
1200 case GL_ALPHA_BITS:
1201 case GL_DEPTH_BITS:
1202 case GL_STENCIL_BITS:
1203 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1204 case GL_CULL_FACE_MODE:
1205 case GL_FRONT_FACE:
1206 case GL_ACTIVE_TEXTURE:
1207 case GL_STENCIL_FUNC:
1208 case GL_STENCIL_VALUE_MASK:
1209 case GL_STENCIL_REF:
1210 case GL_STENCIL_FAIL:
1211 case GL_STENCIL_PASS_DEPTH_FAIL:
1212 case GL_STENCIL_PASS_DEPTH_PASS:
1213 case GL_STENCIL_BACK_FUNC:
1214 case GL_STENCIL_BACK_VALUE_MASK:
1215 case GL_STENCIL_BACK_REF:
1216 case GL_STENCIL_BACK_FAIL:
1217 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1218 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1219 case GL_DEPTH_FUNC:
1220 case GL_BLEND_SRC_RGB:
1221 case GL_BLEND_SRC_ALPHA:
1222 case GL_BLEND_DST_RGB:
1223 case GL_BLEND_DST_ALPHA:
1224 case GL_BLEND_EQUATION_RGB:
1225 case GL_BLEND_EQUATION_ALPHA:
1226 case GL_STENCIL_WRITEMASK:
1227 case GL_STENCIL_BACK_WRITEMASK:
1228 case GL_STENCIL_CLEAR_VALUE:
1229 case GL_SUBPIXEL_BITS:
1230 case GL_MAX_TEXTURE_SIZE:
1231 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1232 case GL_SAMPLE_BUFFERS:
1233 case GL_SAMPLES:
1234 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1235 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1236 case GL_TEXTURE_BINDING_2D:
1237 case GL_TEXTURE_BINDING_CUBE_MAP:
1238 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1239 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001240 {
1241 *type = GL_INT;
1242 *numParams = 1;
1243 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001244 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 case GL_MAX_SAMPLES_ANGLE:
1246 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001247 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 {
1249 *type = GL_INT;
1250 *numParams = 1;
1251 }
1252 else
1253 {
1254 return false;
1255 }
1256 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001257 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001258 case GL_MAX_VIEWPORT_DIMS:
1259 {
1260 *type = GL_INT;
1261 *numParams = 2;
1262 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001263 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001264 case GL_VIEWPORT:
1265 case GL_SCISSOR_BOX:
1266 {
1267 *type = GL_INT;
1268 *numParams = 4;
1269 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001270 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001271 case GL_SHADER_COMPILER:
1272 case GL_SAMPLE_COVERAGE_INVERT:
1273 case GL_DEPTH_WRITEMASK:
1274 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1275 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1276 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1277 case GL_SAMPLE_COVERAGE:
1278 case GL_SCISSOR_TEST:
1279 case GL_STENCIL_TEST:
1280 case GL_DEPTH_TEST:
1281 case GL_BLEND:
1282 case GL_DITHER:
1283 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1284 {
1285 *type = GL_BOOL;
1286 *numParams = 1;
1287 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001288 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001289 case GL_COLOR_WRITEMASK:
1290 {
1291 *type = GL_BOOL;
1292 *numParams = 4;
1293 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001294 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001295 case GL_POLYGON_OFFSET_FACTOR:
1296 case GL_POLYGON_OFFSET_UNITS:
1297 case GL_SAMPLE_COVERAGE_VALUE:
1298 case GL_DEPTH_CLEAR_VALUE:
1299 case GL_LINE_WIDTH:
1300 {
1301 *type = GL_FLOAT;
1302 *numParams = 1;
1303 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001304 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001305 case GL_ALIASED_LINE_WIDTH_RANGE:
1306 case GL_ALIASED_POINT_SIZE_RANGE:
1307 case GL_DEPTH_RANGE:
1308 {
1309 *type = GL_FLOAT;
1310 *numParams = 2;
1311 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001312 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001313 case GL_COLOR_CLEAR_VALUE:
1314 case GL_BLEND_COLOR:
1315 {
1316 *type = GL_FLOAT;
1317 *numParams = 4;
1318 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001319 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001320 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001321 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001322 {
1323 return false;
1324 }
1325 *type = GL_FLOAT;
1326 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001327 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001328 case GL_TIMESTAMP_EXT:
1329 if (!mExtensions.disjointTimerQuery)
1330 {
1331 return false;
1332 }
1333 *type = GL_INT_64_ANGLEX;
1334 *numParams = 1;
1335 return true;
1336 case GL_GPU_DISJOINT_EXT:
1337 if (!mExtensions.disjointTimerQuery)
1338 {
1339 return false;
1340 }
1341 *type = GL_INT;
1342 *numParams = 1;
1343 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001344 }
1345
Geoff Lang70d0f492015-12-10 17:45:46 -05001346 if (mExtensions.debug)
1347 {
1348 switch (pname)
1349 {
1350 case GL_DEBUG_LOGGED_MESSAGES:
1351 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1352 case GL_DEBUG_GROUP_STACK_DEPTH:
1353 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1354 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1355 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1356 case GL_MAX_LABEL_LENGTH:
1357 *type = GL_INT;
1358 *numParams = 1;
1359 return true;
1360
1361 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1362 case GL_DEBUG_OUTPUT:
1363 *type = GL_BOOL;
1364 *numParams = 1;
1365 return true;
1366 }
1367 }
1368
Austin Kinrossbc781f32015-10-26 09:27:38 -07001369 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1370 switch (pname)
1371 {
1372 case GL_PACK_ROW_LENGTH:
1373 case GL_PACK_SKIP_ROWS:
1374 case GL_PACK_SKIP_PIXELS:
1375 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1376 {
1377 return false;
1378 }
1379 *type = GL_INT;
1380 *numParams = 1;
1381 return true;
1382 case GL_UNPACK_ROW_LENGTH:
1383 case GL_UNPACK_SKIP_ROWS:
1384 case GL_UNPACK_SKIP_PIXELS:
1385 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1386 {
1387 return false;
1388 }
1389 *type = GL_INT;
1390 *numParams = 1;
1391 return true;
1392 case GL_VERTEX_ARRAY_BINDING:
1393 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1394 {
1395 return false;
1396 }
1397 *type = GL_INT;
1398 *numParams = 1;
1399 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001400 case GL_PIXEL_PACK_BUFFER_BINDING:
1401 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1402 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1403 {
1404 return false;
1405 }
1406 *type = GL_INT;
1407 *numParams = 1;
1408 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001409 }
1410
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001411 if (mClientVersion < 3)
1412 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001413 return false;
1414 }
1415
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001416 // Check for ES3.0+ parameter names
1417 switch (pname)
1418 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001419 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1420 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001421 case GL_UNIFORM_BUFFER_BINDING:
1422 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001423 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001424 case GL_COPY_READ_BUFFER_BINDING:
1425 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001426 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001427 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001428 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001429 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001430 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1431 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1432 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001433 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1434 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001435 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001436 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1437 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001438 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1439 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001440 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001441 case GL_MAJOR_VERSION:
1442 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001443 case GL_MAX_ELEMENTS_INDICES:
1444 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001445 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001446 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001447 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001448 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001449 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001450 {
1451 *type = GL_INT;
1452 *numParams = 1;
1453 }
1454 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001455
1456 case GL_MAX_ELEMENT_INDEX:
1457 case GL_MAX_UNIFORM_BLOCK_SIZE:
1458 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1459 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1460 case GL_MAX_SERVER_WAIT_TIMEOUT:
1461 {
1462 *type = GL_INT_64_ANGLEX;
1463 *numParams = 1;
1464 }
1465 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001466
1467 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001468 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001469 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001470 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001471 {
1472 *type = GL_BOOL;
1473 *numParams = 1;
1474 }
1475 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001476
1477 case GL_MAX_TEXTURE_LOD_BIAS:
1478 {
1479 *type = GL_FLOAT;
1480 *numParams = 1;
1481 }
1482 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001483 }
1484
1485 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001486}
1487
Shannon Woods1b2fb852013-08-19 14:28:48 -04001488bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1489{
1490 if (mClientVersion < 3)
1491 {
1492 return false;
1493 }
1494
1495 switch (target)
1496 {
1497 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1498 case GL_UNIFORM_BUFFER_BINDING:
1499 {
1500 *type = GL_INT;
1501 *numParams = 1;
1502 }
1503 return true;
1504 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1505 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1506 case GL_UNIFORM_BUFFER_START:
1507 case GL_UNIFORM_BUFFER_SIZE:
1508 {
1509 *type = GL_INT_64_ANGLEX;
1510 *numParams = 1;
1511 }
1512 }
1513
1514 return false;
1515}
1516
Geoff Langf6db0982015-08-25 13:04:00 -04001517Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001518{
Jamie Madill1b94d432015-08-07 13:23:23 -04001519 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001520 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001521 if (error.isError())
1522 {
1523 return error;
1524 }
1525
Geoff Langf6db0982015-08-25 13:04:00 -04001526 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001527
1528 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001529}
1530
Geoff Langf6db0982015-08-25 13:04:00 -04001531Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1532{
1533 syncRendererState();
1534 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1535 if (error.isError())
1536 {
1537 return error;
1538 }
1539
1540 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1541
1542 return Error(GL_NO_ERROR);
1543}
1544
1545Error Context::drawElements(GLenum mode,
1546 GLsizei count,
1547 GLenum type,
1548 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001549 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001550{
Jamie Madill1b94d432015-08-07 13:23:23 -04001551 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001552 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1553}
1554
1555Error Context::drawElementsInstanced(GLenum mode,
1556 GLsizei count,
1557 GLenum type,
1558 const GLvoid *indices,
1559 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001560 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001561{
1562 syncRendererState();
1563 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1564 indexRange);
1565}
1566
1567Error Context::drawRangeElements(GLenum mode,
1568 GLuint start,
1569 GLuint end,
1570 GLsizei count,
1571 GLenum type,
1572 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001573 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001574{
1575 syncRendererState();
1576 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1577 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001578}
1579
Geoff Lang129753a2015-01-09 16:52:09 -05001580Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001581{
Geoff Lang129753a2015-01-09 16:52:09 -05001582 return mRenderer->flush();
1583}
1584
1585Error Context::finish()
1586{
1587 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001588}
1589
Austin Kinross6ee1e782015-05-29 17:05:37 -07001590void Context::insertEventMarker(GLsizei length, const char *marker)
1591{
1592 ASSERT(mRenderer);
1593 mRenderer->insertEventMarker(length, marker);
1594}
1595
1596void Context::pushGroupMarker(GLsizei length, const char *marker)
1597{
1598 ASSERT(mRenderer);
1599 mRenderer->pushGroupMarker(length, marker);
1600}
1601
1602void Context::popGroupMarker()
1603{
1604 ASSERT(mRenderer);
1605 mRenderer->popGroupMarker();
1606}
1607
Geoff Langda5777c2014-07-11 09:52:58 -04001608void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001609{
Geoff Langda5777c2014-07-11 09:52:58 -04001610 if (error.isError())
1611 {
1612 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001613
1614 if (!error.getMessage().empty())
1615 {
1616 auto &debug = mState.getDebug();
1617 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1618 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1619 }
Geoff Langda5777c2014-07-11 09:52:58 -04001620 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001621}
1622
1623// Get one of the recorded errors and clear its flag, if any.
1624// [OpenGL ES 2.0.24] section 2.5 page 13.
1625GLenum Context::getError()
1626{
Geoff Langda5777c2014-07-11 09:52:58 -04001627 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001628 {
Geoff Langda5777c2014-07-11 09:52:58 -04001629 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630 }
Geoff Langda5777c2014-07-11 09:52:58 -04001631 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001632 {
Geoff Langda5777c2014-07-11 09:52:58 -04001633 GLenum error = *mErrors.begin();
1634 mErrors.erase(mErrors.begin());
1635 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001637}
1638
1639GLenum Context::getResetStatus()
1640{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001641 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001642 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001643 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001644 // mResetStatus will be set by the markContextLost callback
1645 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001646 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001647 {
1648 mRenderer->notifyDeviceLost();
1649 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001650 }
1651
1652 GLenum status = mResetStatus;
1653
1654 if (mResetStatus != GL_NO_ERROR)
1655 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001656 ASSERT(mContextLost);
1657
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001658 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001659 {
1660 mResetStatus = GL_NO_ERROR;
1661 }
1662 }
Jamie Madill893ab082014-05-16 16:56:10 -04001663
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001664 return status;
1665}
1666
1667bool Context::isResetNotificationEnabled()
1668{
1669 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1670}
1671
Corentin Walleze3b10e82015-05-20 11:06:25 -04001672const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001673{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001674 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001675}
1676
1677EGLenum Context::getClientType() const
1678{
1679 return mClientType;
1680}
1681
1682EGLenum Context::getRenderBuffer() const
1683{
Corentin Wallez37c39792015-08-20 14:19:46 -04001684 auto framebufferIt = mFramebufferMap.find(0);
1685 if (framebufferIt != mFramebufferMap.end())
1686 {
1687 const Framebuffer *framebuffer = framebufferIt->second;
1688 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1689
1690 ASSERT(backAttachment != nullptr);
1691 return backAttachment->getSurface()->getRenderBuffer();
1692 }
1693 else
1694 {
1695 return EGL_NONE;
1696 }
Régis Fénéon83107972015-02-05 12:57:44 +01001697}
1698
Geoff Lang36167ab2015-12-07 10:27:14 -05001699void Context::checkVertexArrayAllocation(GLuint vertexArray)
1700{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001701 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001702 if (!getVertexArray(vertexArray))
1703 {
1704 VertexArray *vertexArrayObject =
1705 new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
1706 mVertexArrayMap[vertexArray] = vertexArrayObject;
1707 }
1708}
1709
1710void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
1711{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001712 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001713 if (!getTransformFeedback(transformFeedback))
1714 {
1715 TransformFeedback *transformFeedbackObject =
1716 new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps);
1717 transformFeedbackObject->addRef();
1718 mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
1719 }
1720}
1721
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001722Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1723{
1724 // Can be called from Bind without a prior call to Gen.
1725 auto framebufferIt = mFramebufferMap.find(framebuffer);
1726 bool neverCreated = framebufferIt == mFramebufferMap.end();
1727 if (neverCreated || framebufferIt->second == nullptr)
1728 {
1729 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1730 if (neverCreated)
1731 {
1732 mFramebufferHandleAllocator.reserve(framebuffer);
1733 mFramebufferMap[framebuffer] = newFBO;
1734 return newFBO;
1735 }
1736
1737 framebufferIt->second = newFBO;
1738 }
1739
1740 return framebufferIt->second;
1741}
1742
Geoff Lang36167ab2015-12-07 10:27:14 -05001743bool Context::isVertexArrayGenerated(GLuint vertexArray)
1744{
1745 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1746}
1747
1748bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1749{
1750 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1751}
1752
Shannon Woods53a94a82014-06-24 15:20:36 -04001753void Context::detachTexture(GLuint texture)
1754{
1755 // Simple pass-through to State's detachTexture method, as textures do not require
1756 // allocation map management either here or in the resource manager at detach time.
1757 // Zero textures are held by the Context, and we don't attempt to request them from
1758 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001759 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001760}
1761
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001762void Context::detachBuffer(GLuint buffer)
1763{
Yuly Novikov5807a532015-12-03 13:01:22 -05001764 // Simple pass-through to State's detachBuffer method, since
1765 // only buffer attachments to container objects that are bound to the current context
1766 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001767
Yuly Novikov5807a532015-12-03 13:01:22 -05001768 // [OpenGL ES 3.2] section 5.1.2 page 45:
1769 // Attachments to unbound container objects, such as
1770 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1771 // are not affected and continue to act as references on the deleted object
1772 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001773}
1774
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001775void Context::detachFramebuffer(GLuint framebuffer)
1776{
Shannon Woods53a94a82014-06-24 15:20:36 -04001777 // Framebuffer detachment is handled by Context, because 0 is a valid
1778 // Framebuffer object, and a pointer to it must be passed from Context
1779 // to State at binding time.
1780
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001781 // [OpenGL ES 2.0.24] section 4.4 page 107:
1782 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1783 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1784
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001785 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001786 {
1787 bindReadFramebuffer(0);
1788 }
1789
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001790 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001791 {
1792 bindDrawFramebuffer(0);
1793 }
1794}
1795
1796void Context::detachRenderbuffer(GLuint renderbuffer)
1797{
Shannon Woods53a94a82014-06-24 15:20:36 -04001798 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001799}
1800
Jamie Madill57a89722013-07-02 11:57:03 -04001801void Context::detachVertexArray(GLuint vertexArray)
1802{
Jamie Madill77a72f62015-04-14 11:18:32 -04001803 // Vertex array detachment is handled by Context, because 0 is a valid
1804 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001805 // binding time.
1806
Jamie Madill57a89722013-07-02 11:57:03 -04001807 // [OpenGL ES 3.0.2] section 2.10 page 43:
1808 // If a vertex array object that is currently bound is deleted, the binding
1809 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001810 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001811 {
1812 bindVertexArray(0);
1813 }
1814}
1815
Geoff Langc8058452014-02-03 12:04:11 -05001816void Context::detachTransformFeedback(GLuint transformFeedback)
1817{
Shannon Woods53a94a82014-06-24 15:20:36 -04001818 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001819}
1820
Jamie Madilldc356042013-07-19 16:36:57 -04001821void Context::detachSampler(GLuint sampler)
1822{
Shannon Woods53a94a82014-06-24 15:20:36 -04001823 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001824}
1825
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001826void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1827{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001828 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001829}
1830
Jamie Madille29d1672013-07-19 16:36:57 -04001831void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1832{
1833 mResourceManager->checkSamplerAllocation(sampler);
1834
1835 Sampler *samplerObject = getSampler(sampler);
1836 ASSERT(samplerObject);
1837
Geoff Lang69cce582015-09-17 13:20:36 -04001838 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001839 switch (pname)
1840 {
Geoff Lang69cce582015-09-17 13:20:36 -04001841 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1842 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1843 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1844 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1845 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1846 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1847 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1848 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1849 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1850 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1851 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001852 }
Geoff Lang69cce582015-09-17 13:20:36 -04001853 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001854}
1855
1856void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1857{
1858 mResourceManager->checkSamplerAllocation(sampler);
1859
1860 Sampler *samplerObject = getSampler(sampler);
1861 ASSERT(samplerObject);
1862
Geoff Lang69cce582015-09-17 13:20:36 -04001863 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001864 switch (pname)
1865 {
Geoff Lang69cce582015-09-17 13:20:36 -04001866 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1867 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1868 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1869 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1870 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1871 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1872 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1873 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1874 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1875 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1876 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001877 }
Geoff Lang69cce582015-09-17 13:20:36 -04001878 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001879}
1880
Jamie Madill9675b802013-07-19 16:36:59 -04001881GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1882{
1883 mResourceManager->checkSamplerAllocation(sampler);
1884
1885 Sampler *samplerObject = getSampler(sampler);
1886 ASSERT(samplerObject);
1887
Geoff Lang69cce582015-09-17 13:20:36 -04001888 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001889 switch (pname)
1890 {
Geoff Lang69cce582015-09-17 13:20:36 -04001891 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1892 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1893 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1894 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1895 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1896 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1897 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
1898 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
1899 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1900 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1901 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001902 }
Geoff Lang69cce582015-09-17 13:20:36 -04001903 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001904}
1905
1906GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
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 Madill9675b802013-07-19 16:36:59 -04001914 switch (pname)
1915 {
Geoff Lang69cce582015-09-17 13:20:36 -04001916 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1917 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1918 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1919 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1920 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1921 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1922 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1923 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1924 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1925 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1926 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001927 }
Geoff Lang69cce582015-09-17 13:20:36 -04001928 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001929}
1930
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001931void Context::initRendererString()
1932{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001933 std::ostringstream rendererString;
1934 rendererString << "ANGLE (";
1935 rendererString << mRenderer->getRendererDescription();
1936 rendererString << ")";
1937
Geoff Langcec35902014-04-16 10:52:36 -04001938 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001939}
1940
Geoff Langc0b9ef42014-07-02 10:02:37 -04001941const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001942{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001943 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001944}
1945
Geoff Langcec35902014-04-16 10:52:36 -04001946void Context::initExtensionStrings()
1947{
Geoff Lang493daf52014-07-03 13:38:44 -04001948 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001949
Geoff Langc0b9ef42014-07-02 10:02:37 -04001950 std::ostringstream combinedStringStream;
1951 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1952 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001953}
1954
Geoff Langc0b9ef42014-07-02 10:02:37 -04001955const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001956{
1957 return mExtensionString;
1958}
1959
Geoff Langc0b9ef42014-07-02 10:02:37 -04001960const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04001961{
1962 return mExtensionStrings[idx];
1963}
1964
1965size_t Context::getExtensionStringCount() const
1966{
1967 return mExtensionStrings.size();
1968}
1969
Geoff Lang493daf52014-07-03 13:38:44 -04001970void Context::initCaps(GLuint clientVersion)
1971{
1972 mCaps = mRenderer->getRendererCaps();
1973
1974 mExtensions = mRenderer->getRendererExtensions();
1975
Austin Kinross02df7962015-07-01 10:03:42 -07001976 mLimitations = mRenderer->getRendererLimitations();
1977
Geoff Lang493daf52014-07-03 13:38:44 -04001978 if (clientVersion < 3)
1979 {
1980 // Disable ES3+ extensions
1981 mExtensions.colorBufferFloat = false;
1982 }
1983
1984 if (clientVersion > 2)
1985 {
1986 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
1987 //mExtensions.sRGB = false;
1988 }
1989
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 // Explicitly enable GL_KHR_debug
1991 mExtensions.debug = true;
1992 mExtensions.maxDebugMessageLength = 1024;
1993 mExtensions.maxDebugLoggedMessages = 1024;
1994 mExtensions.maxDebugGroupStackDepth = 1024;
1995 mExtensions.maxLabelLength = 1024;
1996
Geoff Lang301d1612014-07-09 10:34:37 -04001997 // Apply implementation limits
1998 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04001999 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2000 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2001
2002 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002003
Geoff Lang900013c2014-07-07 11:32:19 -04002004 mCaps.compressedTextureFormats.clear();
2005
Geoff Lang493daf52014-07-03 13:38:44 -04002006 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2007 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2008 {
2009 GLenum format = i->first;
2010 TextureCaps formatCaps = i->second;
2011
Geoff Lang5d601382014-07-22 15:14:06 -04002012 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002013
Geoff Lang0d8b7242015-09-09 14:56:53 -04002014 // Update the format caps based on the client version and extensions.
2015 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2016 // ES3.
2017 formatCaps.texturable =
2018 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2019 formatCaps.renderable =
2020 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2021 formatCaps.filterable =
2022 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002023
2024 // OpenGL ES does not support multisampling with integer formats
2025 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002026 {
Geoff Langd87878e2014-09-19 15:42:59 -04002027 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002028 }
Geoff Langd87878e2014-09-19 15:42:59 -04002029
2030 if (formatCaps.texturable && formatInfo.compressed)
2031 {
2032 mCaps.compressedTextureFormats.push_back(format);
2033 }
2034
2035 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002036 }
2037}
2038
Jamie Madill1b94d432015-08-07 13:23:23 -04002039void Context::syncRendererState()
2040{
2041 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002042 mRenderer->syncState(mState, dirtyBits);
2043 mState.clearDirtyBits();
2044 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002045}
2046
2047void Context::syncRendererState(const State::DirtyBits &bitMask)
2048{
2049 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002050 mRenderer->syncState(mState, dirtyBits);
2051 mState.clearDirtyBits(dirtyBits);
2052
2053 // TODO(jmadill): Filter objects by bitMask somehow?
2054 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002055}
Jamie Madillc29968b2016-01-20 11:17:23 -05002056
2057void Context::blitFramebuffer(GLint srcX0,
2058 GLint srcY0,
2059 GLint srcX1,
2060 GLint srcY1,
2061 GLint dstX0,
2062 GLint dstY0,
2063 GLint dstX1,
2064 GLint dstY1,
2065 GLbitfield mask,
2066 GLenum filter)
2067{
2068 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2069 ASSERT(readFramebuffer);
2070
2071 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2072 ASSERT(drawFramebuffer);
2073
2074 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2075 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2076
2077 syncRendererState(mState.blitStateBitMask());
2078
2079 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2080 if (error.isError())
2081 {
2082 recordError(error);
2083 return;
2084 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002085}
Jamie Madillc29968b2016-01-20 11:17:23 -05002086
2087void Context::clear(GLbitfield mask)
2088{
2089 // Sync the clear state
2090 syncRendererState(mState.clearStateBitMask());
2091
2092 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2093 if (error.isError())
2094 {
2095 recordError(error);
2096 }
2097}
2098
2099void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2100{
2101 // Sync the clear state
2102 syncRendererState(mState.clearStateBitMask());
2103
2104 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2105 if (error.isError())
2106 {
2107 recordError(error);
2108 }
2109}
2110
2111void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2112{
2113 // Sync the clear state
2114 syncRendererState(mState.clearStateBitMask());
2115
2116 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2117 if (error.isError())
2118 {
2119 recordError(error);
2120 }
2121}
2122
2123void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2124{
2125 // Sync the clear state
2126 syncRendererState(mState.clearStateBitMask());
2127
2128 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2129 if (error.isError())
2130 {
2131 recordError(error);
2132 }
2133}
2134
2135void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2136{
2137 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2138 ASSERT(framebufferObject);
2139
2140 // If a buffer is not present, the clear has no effect
2141 if (framebufferObject->getDepthbuffer() == nullptr &&
2142 framebufferObject->getStencilbuffer() == nullptr)
2143 {
2144 return;
2145 }
2146
2147 // Sync the clear state
2148 syncRendererState(mState.clearStateBitMask());
2149
2150 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2151 if (error.isError())
2152 {
2153 recordError(error);
2154 }
2155}
2156
2157void Context::readPixels(GLint x,
2158 GLint y,
2159 GLsizei width,
2160 GLsizei height,
2161 GLenum format,
2162 GLenum type,
2163 GLvoid *pixels)
2164{
2165 // Sync pack state
2166 syncRendererState(mState.packStateBitMask());
2167
2168 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2169 ASSERT(framebufferObject);
2170
2171 Rectangle area(x, y, width, height);
2172 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2173 if (error.isError())
2174 {
2175 recordError(error);
2176 }
2177}
2178
2179void Context::copyTexImage2D(GLenum target,
2180 GLint level,
2181 GLenum internalformat,
2182 GLint x,
2183 GLint y,
2184 GLsizei width,
2185 GLsizei height,
2186 GLint border)
2187{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002188 // Only sync the read FBO
2189 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2190
Jamie Madillc29968b2016-01-20 11:17:23 -05002191 Rectangle sourceArea(x, y, width, height);
2192
2193 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2194 Texture *texture =
2195 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2196 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2197 if (error.isError())
2198 {
2199 recordError(error);
2200 }
2201}
2202
2203void Context::copyTexSubImage2D(GLenum target,
2204 GLint level,
2205 GLint xoffset,
2206 GLint yoffset,
2207 GLint x,
2208 GLint y,
2209 GLsizei width,
2210 GLsizei height)
2211{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002212 // Only sync the read FBO
2213 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2214
Jamie Madillc29968b2016-01-20 11:17:23 -05002215 Offset destOffset(xoffset, yoffset, 0);
2216 Rectangle sourceArea(x, y, width, height);
2217
2218 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2219 Texture *texture =
2220 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2221 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2222 if (error.isError())
2223 {
2224 recordError(error);
2225 }
2226}
2227
2228void Context::copyTexSubImage3D(GLenum target,
2229 GLint level,
2230 GLint xoffset,
2231 GLint yoffset,
2232 GLint zoffset,
2233 GLint x,
2234 GLint y,
2235 GLsizei width,
2236 GLsizei height)
2237{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002238 // Only sync the read FBO
2239 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2240
Jamie Madillc29968b2016-01-20 11:17:23 -05002241 Offset destOffset(xoffset, yoffset, zoffset);
2242 Rectangle sourceArea(x, y, width, height);
2243
2244 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2245 Texture *texture = getTargetTexture(target);
2246 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2247 if (error.isError())
2248 {
2249 recordError(error);
2250 }
2251}
2252
2253void Context::framebufferTexture2D(GLenum target,
2254 GLenum attachment,
2255 GLenum textarget,
2256 GLuint texture,
2257 GLint level)
2258{
2259 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2260 ASSERT(framebuffer);
2261
2262 if (texture != 0)
2263 {
2264 Texture *textureObj = getTexture(texture);
2265
2266 ImageIndex index = ImageIndex::MakeInvalid();
2267
2268 if (textarget == GL_TEXTURE_2D)
2269 {
2270 index = ImageIndex::Make2D(level);
2271 }
2272 else
2273 {
2274 ASSERT(IsCubeMapTextureTarget(textarget));
2275 index = ImageIndex::MakeCube(textarget, level);
2276 }
2277
2278 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2279 }
2280 else
2281 {
2282 framebuffer->resetAttachment(attachment);
2283 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002284
2285 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002286}
2287
2288void Context::framebufferRenderbuffer(GLenum target,
2289 GLenum attachment,
2290 GLenum renderbuffertarget,
2291 GLuint renderbuffer)
2292{
2293 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2294 ASSERT(framebuffer);
2295
2296 if (renderbuffer != 0)
2297 {
2298 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2299 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2300 renderbufferObject);
2301 }
2302 else
2303 {
2304 framebuffer->resetAttachment(attachment);
2305 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002306
2307 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002308}
2309
2310void Context::framebufferTextureLayer(GLenum target,
2311 GLenum attachment,
2312 GLuint texture,
2313 GLint level,
2314 GLint layer)
2315{
2316 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2317 ASSERT(framebuffer);
2318
2319 if (texture != 0)
2320 {
2321 Texture *textureObject = getTexture(texture);
2322
2323 ImageIndex index = ImageIndex::MakeInvalid();
2324
2325 if (textureObject->getTarget() == GL_TEXTURE_3D)
2326 {
2327 index = ImageIndex::Make3D(level, layer);
2328 }
2329 else
2330 {
2331 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2332 index = ImageIndex::Make2DArray(level, layer);
2333 }
2334
2335 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2336 }
2337 else
2338 {
2339 framebuffer->resetAttachment(attachment);
2340 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002341
2342 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002343}
2344
2345void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2346{
2347 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2348 ASSERT(framebuffer);
2349 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002350 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002351}
2352
2353void Context::readBuffer(GLenum mode)
2354{
2355 Framebuffer *readFBO = mState.getReadFramebuffer();
2356 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002357 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002358}
2359
2360void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2361{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002362 // Only sync the FBO
2363 mState.syncDirtyObject(target);
2364
Jamie Madillc29968b2016-01-20 11:17:23 -05002365 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2366 ASSERT(framebuffer);
2367
2368 // The specification isn't clear what should be done when the framebuffer isn't complete.
2369 // We leave it up to the framebuffer implementation to decide what to do.
2370 Error error = framebuffer->discard(numAttachments, attachments);
2371 if (error.isError())
2372 {
2373 recordError(error);
2374 }
2375}
2376
2377void Context::invalidateFramebuffer(GLenum target,
2378 GLsizei numAttachments,
2379 const GLenum *attachments)
2380{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002381 // Only sync the FBO
2382 mState.syncDirtyObject(target);
2383
Jamie Madillc29968b2016-01-20 11:17:23 -05002384 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2385 ASSERT(framebuffer);
2386
2387 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2388 {
2389 Error error = framebuffer->invalidate(numAttachments, attachments);
2390 if (error.isError())
2391 {
2392 recordError(error);
2393 return;
2394 }
2395 }
2396}
2397
2398void Context::invalidateSubFramebuffer(GLenum target,
2399 GLsizei numAttachments,
2400 const GLenum *attachments,
2401 GLint x,
2402 GLint y,
2403 GLsizei width,
2404 GLsizei height)
2405{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002406 // Only sync the FBO
2407 mState.syncDirtyObject(target);
2408
Jamie Madillc29968b2016-01-20 11:17:23 -05002409 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2410 ASSERT(framebuffer);
2411
2412 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2413 {
2414 Rectangle area(x, y, width, height);
2415 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2416 if (error.isError())
2417 {
2418 recordError(error);
2419 return;
2420 }
2421 }
2422}
2423
Jamie Madill73a84962016-02-12 09:27:23 -05002424void Context::texImage2D(GLenum target,
2425 GLint level,
2426 GLint internalformat,
2427 GLsizei width,
2428 GLsizei height,
2429 GLint border,
2430 GLenum format,
2431 GLenum type,
2432 const GLvoid *pixels)
2433{
2434 // Sync the unpack state
2435 syncRendererState(mState.unpackStateBitMask());
2436
2437 Extents size(width, height, 1);
2438 Texture *texture =
2439 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2440 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2441 format, type, reinterpret_cast<const uint8_t *>(pixels));
2442 if (error.isError())
2443 {
2444 recordError(error);
2445 }
2446}
2447
2448void Context::texImage3D(GLenum target,
2449 GLint level,
2450 GLint internalformat,
2451 GLsizei width,
2452 GLsizei height,
2453 GLsizei depth,
2454 GLint border,
2455 GLenum format,
2456 GLenum type,
2457 const GLvoid *pixels)
2458{
2459 // Sync the unpack state
2460 syncRendererState(mState.unpackStateBitMask());
2461
2462 Extents size(width, height, depth);
2463 Texture *texture = getTargetTexture(target);
2464 Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size,
2465 format, type, reinterpret_cast<const uint8_t *>(pixels));
2466 if (error.isError())
2467 {
2468 recordError(error);
2469 }
2470}
2471
2472void Context::texSubImage2D(GLenum target,
2473 GLint level,
2474 GLint xoffset,
2475 GLint yoffset,
2476 GLsizei width,
2477 GLsizei height,
2478 GLenum format,
2479 GLenum type,
2480 const GLvoid *pixels)
2481{
2482 // Zero sized uploads are valid but no-ops
2483 if (width == 0 || height == 0)
2484 {
2485 return;
2486 }
2487
2488 // Sync the unpack state
2489 syncRendererState(mState.unpackStateBitMask());
2490
2491 Box area(xoffset, yoffset, 0, width, height, 1);
2492 Texture *texture =
2493 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2494 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2495 reinterpret_cast<const uint8_t *>(pixels));
2496 if (error.isError())
2497 {
2498 recordError(error);
2499 }
2500}
2501
2502void Context::texSubImage3D(GLenum target,
2503 GLint level,
2504 GLint xoffset,
2505 GLint yoffset,
2506 GLint zoffset,
2507 GLsizei width,
2508 GLsizei height,
2509 GLsizei depth,
2510 GLenum format,
2511 GLenum type,
2512 const GLvoid *pixels)
2513{
2514 // Zero sized uploads are valid but no-ops
2515 if (width == 0 || height == 0 || depth == 0)
2516 {
2517 return;
2518 }
2519
2520 // Sync the unpack state
2521 syncRendererState(mState.unpackStateBitMask());
2522
2523 Box area(xoffset, yoffset, zoffset, width, height, depth);
2524 Texture *texture = getTargetTexture(target);
2525 Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type,
2526 reinterpret_cast<const uint8_t *>(pixels));
2527 if (error.isError())
2528 {
2529 recordError(error);
2530 }
2531}
2532
2533void Context::compressedTexImage2D(GLenum target,
2534 GLint level,
2535 GLenum internalformat,
2536 GLsizei width,
2537 GLsizei height,
2538 GLint border,
2539 GLsizei imageSize,
2540 const GLvoid *data)
2541{
2542 // Sync the unpack state
2543 syncRendererState(mState.unpackStateBitMask());
2544
2545 Extents size(width, height, 1);
2546 Texture *texture =
2547 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2548 Error error =
2549 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2550 imageSize, reinterpret_cast<const uint8_t *>(data));
2551 if (error.isError())
2552 {
2553 recordError(error);
2554 }
2555}
2556
2557void Context::compressedTexImage3D(GLenum target,
2558 GLint level,
2559 GLenum internalformat,
2560 GLsizei width,
2561 GLsizei height,
2562 GLsizei depth,
2563 GLint border,
2564 GLsizei imageSize,
2565 const GLvoid *data)
2566{
2567 // Sync the unpack state
2568 syncRendererState(mState.unpackStateBitMask());
2569
2570 Extents size(width, height, depth);
2571 Texture *texture = getTargetTexture(target);
2572 Error error =
2573 texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size,
2574 imageSize, reinterpret_cast<const uint8_t *>(data));
2575 if (error.isError())
2576 {
2577 recordError(error);
2578 }
2579}
2580
2581void Context::compressedTexSubImage2D(GLenum target,
2582 GLint level,
2583 GLint xoffset,
2584 GLint yoffset,
2585 GLsizei width,
2586 GLsizei height,
2587 GLenum format,
2588 GLsizei imageSize,
2589 const GLvoid *data)
2590{
2591 // Sync the unpack state
2592 syncRendererState(mState.unpackStateBitMask());
2593
2594 Box area(xoffset, yoffset, 0, width, height, 1);
2595 Texture *texture =
2596 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2597 Error error =
2598 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2599 imageSize, reinterpret_cast<const uint8_t *>(data));
2600 if (error.isError())
2601 {
2602 recordError(error);
2603 }
2604}
2605
2606void Context::compressedTexSubImage3D(GLenum target,
2607 GLint level,
2608 GLint xoffset,
2609 GLint yoffset,
2610 GLint zoffset,
2611 GLsizei width,
2612 GLsizei height,
2613 GLsizei depth,
2614 GLenum format,
2615 GLsizei imageSize,
2616 const GLvoid *data)
2617{
2618 // Zero sized uploads are valid but no-ops
2619 if (width == 0 || height == 0)
2620 {
2621 return;
2622 }
2623
2624 // Sync the unpack state
2625 syncRendererState(mState.unpackStateBitMask());
2626
2627 Box area(xoffset, yoffset, zoffset, width, height, depth);
2628 Texture *texture = getTargetTexture(target);
2629 Error error =
2630 texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format,
2631 imageSize, reinterpret_cast<const uint8_t *>(data));
2632 if (error.isError())
2633 {
2634 recordError(error);
2635 }
2636}
2637
Jamie Madillc29968b2016-01-20 11:17:23 -05002638} // namespace gl