blob: b835c1a45722e654efadcb0002deb7ca49a362ed [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 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000319}
320
Jamie Madill77a72f62015-04-14 11:18:32 -0400321void Context::releaseSurface()
322{
Corentin Wallez37c39792015-08-20 14:19:46 -0400323 ASSERT(mCurrentSurface != nullptr);
324
325 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400326 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400327 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
328 if (mState.getReadFramebuffer() == currentDefault)
329 {
330 mState.setReadFramebufferBinding(nullptr);
331 }
332 if (mState.getDrawFramebuffer() == currentDefault)
333 {
334 mState.setDrawFramebufferBinding(nullptr);
335 }
336 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400337 }
338
Corentin Wallez51706ea2015-08-07 14:39:22 -0400339 mCurrentSurface->setIsCurrent(false);
340 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400341}
342
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000343// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344void Context::markContextLost()
345{
346 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
347 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
348 mContextLost = true;
349}
350
351bool Context::isContextLost()
352{
353 return mContextLost;
354}
355
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356GLuint Context::createBuffer()
357{
358 return mResourceManager->createBuffer();
359}
360
361GLuint Context::createProgram()
362{
363 return mResourceManager->createProgram();
364}
365
366GLuint Context::createShader(GLenum type)
367{
Jamie Madill006cbc52015-09-23 16:47:54 -0400368 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000369}
370
371GLuint Context::createTexture()
372{
373 return mResourceManager->createTexture();
374}
375
376GLuint Context::createRenderbuffer()
377{
378 return mResourceManager->createRenderbuffer();
379}
380
Geoff Lang882033e2014-09-30 11:26:07 -0400381GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400382{
383 GLuint handle = mResourceManager->createFenceSync();
384
Cooper Partind8e62a32015-01-29 15:21:25 -0800385 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400386}
387
Jamie Madill57a89722013-07-02 11:57:03 -0400388GLuint Context::createVertexArray()
389{
Geoff Lang36167ab2015-12-07 10:27:14 -0500390 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
391 mVertexArrayMap[vertexArray] = nullptr;
392 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400393}
394
Jamie Madilldc356042013-07-19 16:36:57 -0400395GLuint Context::createSampler()
396{
397 return mResourceManager->createSampler();
398}
399
Geoff Langc8058452014-02-03 12:04:11 -0500400GLuint Context::createTransformFeedback()
401{
Geoff Lang36167ab2015-12-07 10:27:14 -0500402 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
403 mTransformFeedbackMap[transformFeedback] = nullptr;
404 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500405}
406
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407// Returns an unused framebuffer name
408GLuint Context::createFramebuffer()
409{
410 GLuint handle = mFramebufferHandleAllocator.allocate();
411
412 mFramebufferMap[handle] = NULL;
413
414 return handle;
415}
416
Jamie Madill33dc8432013-07-26 11:55:05 -0400417GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418{
Jamie Madill33dc8432013-07-26 11:55:05 -0400419 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700421 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422
423 return handle;
424}
425
426// Returns an unused query name
427GLuint Context::createQuery()
428{
429 GLuint handle = mQueryHandleAllocator.allocate();
430
431 mQueryMap[handle] = NULL;
432
433 return handle;
434}
435
436void Context::deleteBuffer(GLuint buffer)
437{
438 if (mResourceManager->getBuffer(buffer))
439 {
440 detachBuffer(buffer);
441 }
Jamie Madill893ab082014-05-16 16:56:10 -0400442
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443 mResourceManager->deleteBuffer(buffer);
444}
445
446void Context::deleteShader(GLuint shader)
447{
448 mResourceManager->deleteShader(shader);
449}
450
451void Context::deleteProgram(GLuint program)
452{
453 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454}
455
456void Context::deleteTexture(GLuint texture)
457{
458 if (mResourceManager->getTexture(texture))
459 {
460 detachTexture(texture);
461 }
462
463 mResourceManager->deleteTexture(texture);
464}
465
466void Context::deleteRenderbuffer(GLuint renderbuffer)
467{
468 if (mResourceManager->getRenderbuffer(renderbuffer))
469 {
470 detachRenderbuffer(renderbuffer);
471 }
Jamie Madill893ab082014-05-16 16:56:10 -0400472
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473 mResourceManager->deleteRenderbuffer(renderbuffer);
474}
475
Jamie Madillcd055f82013-07-26 11:55:15 -0400476void Context::deleteFenceSync(GLsync fenceSync)
477{
478 // The spec specifies the underlying Fence object is not deleted until all current
479 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
480 // and since our API is currently designed for being called from a single thread, we can delete
481 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700482 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400483}
484
Jamie Madill57a89722013-07-02 11:57:03 -0400485void Context::deleteVertexArray(GLuint vertexArray)
486{
Geoff Lang36167ab2015-12-07 10:27:14 -0500487 auto iter = mVertexArrayMap.find(vertexArray);
488 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000489 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500490 VertexArray *vertexArrayObject = iter->second;
491 if (vertexArrayObject != nullptr)
492 {
493 detachVertexArray(vertexArray);
494 delete vertexArrayObject;
495 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000496
Geoff Lang36167ab2015-12-07 10:27:14 -0500497 mVertexArrayMap.erase(iter);
498 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400499 }
500}
501
Jamie Madilldc356042013-07-19 16:36:57 -0400502void Context::deleteSampler(GLuint sampler)
503{
504 if (mResourceManager->getSampler(sampler))
505 {
506 detachSampler(sampler);
507 }
508
509 mResourceManager->deleteSampler(sampler);
510}
511
Geoff Langc8058452014-02-03 12:04:11 -0500512void Context::deleteTransformFeedback(GLuint transformFeedback)
513{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500514 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500515 if (iter != mTransformFeedbackMap.end())
516 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500517 TransformFeedback *transformFeedbackObject = iter->second;
518 if (transformFeedbackObject != nullptr)
519 {
520 detachTransformFeedback(transformFeedback);
521 transformFeedbackObject->release();
522 }
523
Geoff Lang50b3fe82015-12-08 14:49:12 +0000524 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500525 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500526 }
527}
528
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000529void Context::deleteFramebuffer(GLuint framebuffer)
530{
531 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
532
533 if (framebufferObject != mFramebufferMap.end())
534 {
535 detachFramebuffer(framebuffer);
536
537 mFramebufferHandleAllocator.release(framebufferObject->first);
538 delete framebufferObject->second;
539 mFramebufferMap.erase(framebufferObject);
540 }
541}
542
Jamie Madill33dc8432013-07-26 11:55:05 -0400543void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000544{
Jamie Madill33dc8432013-07-26 11:55:05 -0400545 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546
Jamie Madill33dc8432013-07-26 11:55:05 -0400547 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400549 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400551 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552 }
553}
554
555void Context::deleteQuery(GLuint query)
556{
557 QueryMap::iterator queryObject = mQueryMap.find(query);
558 if (queryObject != mQueryMap.end())
559 {
560 mQueryHandleAllocator.release(queryObject->first);
561 if (queryObject->second)
562 {
563 queryObject->second->release();
564 }
565 mQueryMap.erase(queryObject);
566 }
567}
568
Geoff Lang70d0f492015-12-10 17:45:46 -0500569Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570{
571 return mResourceManager->getBuffer(handle);
572}
573
Geoff Lang48dcae72014-02-05 16:28:24 -0500574Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575{
576 return mResourceManager->getShader(handle);
577}
578
Geoff Lang48dcae72014-02-05 16:28:24 -0500579Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580{
581 return mResourceManager->getProgram(handle);
582}
583
Jamie Madill570f7c82014-07-03 10:38:54 -0400584Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585{
586 return mResourceManager->getTexture(handle);
587}
588
Geoff Lang70d0f492015-12-10 17:45:46 -0500589Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590{
591 return mResourceManager->getRenderbuffer(handle);
592}
593
Jamie Madillcd055f82013-07-26 11:55:15 -0400594FenceSync *Context::getFenceSync(GLsync handle) const
595{
Minmin Gong794e0002015-04-07 18:31:54 -0700596 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400597}
598
Jamie Madill57a89722013-07-02 11:57:03 -0400599VertexArray *Context::getVertexArray(GLuint handle) const
600{
601 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500602 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400603}
604
Jamie Madilldc356042013-07-19 16:36:57 -0400605Sampler *Context::getSampler(GLuint handle) const
606{
607 return mResourceManager->getSampler(handle);
608}
609
Geoff Langc8058452014-02-03 12:04:11 -0500610TransformFeedback *Context::getTransformFeedback(GLuint handle) const
611{
Geoff Lang36167ab2015-12-07 10:27:14 -0500612 auto iter = mTransformFeedbackMap.find(handle);
613 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500614}
615
Geoff Lang70d0f492015-12-10 17:45:46 -0500616LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
617{
618 switch (identifier)
619 {
620 case GL_BUFFER:
621 return getBuffer(name);
622 case GL_SHADER:
623 return getShader(name);
624 case GL_PROGRAM:
625 return getProgram(name);
626 case GL_VERTEX_ARRAY:
627 return getVertexArray(name);
628 case GL_QUERY:
629 return getQuery(name);
630 case GL_TRANSFORM_FEEDBACK:
631 return getTransformFeedback(name);
632 case GL_SAMPLER:
633 return getSampler(name);
634 case GL_TEXTURE:
635 return getTexture(name);
636 case GL_RENDERBUFFER:
637 return getRenderbuffer(name);
638 case GL_FRAMEBUFFER:
639 return getFramebuffer(name);
640 default:
641 UNREACHABLE();
642 return nullptr;
643 }
644}
645
646LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
647{
648 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
649}
650
Jamie Madilldc356042013-07-19 16:36:57 -0400651bool Context::isSampler(GLuint samplerName) const
652{
653 return mResourceManager->isSampler(samplerName);
654}
655
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656void Context::bindArrayBuffer(unsigned int buffer)
657{
658 mResourceManager->checkBufferAllocation(buffer);
659
Shannon Woods53a94a82014-06-24 15:20:36 -0400660 mState.setArrayBufferBinding(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::bindElementArrayBuffer(unsigned int buffer)
664{
665 mResourceManager->checkBufferAllocation(buffer);
666
Shannon Woods53a94a82014-06-24 15:20:36 -0400667 mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000668}
669
Jamie Madilldedd7b92014-11-05 16:30:36 -0500670void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500672 Texture *texture = NULL;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000673
Jamie Madilldedd7b92014-11-05 16:30:36 -0500674 if (handle == 0)
675 {
676 texture = mZeroTextures[target].get();
677 }
678 else
679 {
680 mResourceManager->checkTextureAllocation(handle, target);
681 texture = getTexture(handle);
682 }
683
684 ASSERT(texture);
685
686 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000687}
688
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500689void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000690{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500691 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
692 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000693}
694
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500695void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000696{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500697 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
698 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000699}
700
701void Context::bindRenderbuffer(GLuint renderbuffer)
702{
703 mResourceManager->checkRenderbufferAllocation(renderbuffer);
704
Shannon Woods53a94a82014-06-24 15:20:36 -0400705 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000706}
707
Jamie Madill57a89722013-07-02 11:57:03 -0400708void Context::bindVertexArray(GLuint vertexArray)
709{
Geoff Lang36167ab2015-12-07 10:27:14 -0500710 checkVertexArrayAllocation(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400711
Shannon Woods53a94a82014-06-24 15:20:36 -0400712 mState.setVertexArrayBinding(getVertexArray(vertexArray));
Jamie Madill57a89722013-07-02 11:57:03 -0400713}
714
Jamie Madilldc356042013-07-19 16:36:57 -0400715void Context::bindSampler(GLuint textureUnit, GLuint sampler)
716{
Geoff Lang76b10c92014-09-05 16:28:14 -0400717 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madilldc356042013-07-19 16:36:57 -0400718 mResourceManager->checkSamplerAllocation(sampler);
719
Shannon Woods53a94a82014-06-24 15:20:36 -0400720 mState.setSamplerBinding(textureUnit, getSampler(sampler));
Jamie Madilldc356042013-07-19 16:36:57 -0400721}
722
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000723void Context::bindGenericUniformBuffer(GLuint buffer)
724{
725 mResourceManager->checkBufferAllocation(buffer);
726
Shannon Woods53a94a82014-06-24 15:20:36 -0400727 mState.setGenericUniformBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000728}
729
730void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000731{
732 mResourceManager->checkBufferAllocation(buffer);
733
Shannon Woods53a94a82014-06-24 15:20:36 -0400734 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000735}
736
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000737void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
738{
739 mResourceManager->checkBufferAllocation(buffer);
740
Geoff Lang045536b2015-03-27 15:17:18 -0400741 mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000742}
743
744void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000745{
746 mResourceManager->checkBufferAllocation(buffer);
747
Geoff Lang045536b2015-03-27 15:17:18 -0400748 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000749}
750
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000751void Context::bindCopyReadBuffer(GLuint buffer)
752{
753 mResourceManager->checkBufferAllocation(buffer);
754
Shannon Woods53a94a82014-06-24 15:20:36 -0400755 mState.setCopyReadBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000756}
757
758void Context::bindCopyWriteBuffer(GLuint buffer)
759{
760 mResourceManager->checkBufferAllocation(buffer);
761
Shannon Woods53a94a82014-06-24 15:20:36 -0400762 mState.setCopyWriteBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000763}
764
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000765void Context::bindPixelPackBuffer(GLuint buffer)
766{
767 mResourceManager->checkBufferAllocation(buffer);
768
Shannon Woods53a94a82014-06-24 15:20:36 -0400769 mState.setPixelPackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000770}
771
772void Context::bindPixelUnpackBuffer(GLuint buffer)
773{
774 mResourceManager->checkBufferAllocation(buffer);
775
Shannon Woods53a94a82014-06-24 15:20:36 -0400776 mState.setPixelUnpackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000777}
778
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779void Context::useProgram(GLuint program)
780{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500781 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000782}
783
Geoff Langc8058452014-02-03 12:04:11 -0500784void Context::bindTransformFeedback(GLuint transformFeedback)
785{
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 checkTransformFeedbackAllocation(transformFeedback);
787
Shannon Woods53a94a82014-06-24 15:20:36 -0400788 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
Geoff Langc8058452014-02-03 12:04:11 -0500789}
790
Geoff Lang5aad9672014-09-08 11:10:42 -0400791Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400794 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795
Geoff Lang5aad9672014-09-08 11:10:42 -0400796 // begin query
797 Error error = queryObject->begin();
798 if (error.isError())
799 {
800 return error;
801 }
802
803 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400804 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805
Geoff Lang5aad9672014-09-08 11:10:42 -0400806 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807}
808
Geoff Lang5aad9672014-09-08 11:10:42 -0400809Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810{
Shannon Woods53a94a82014-06-24 15:20:36 -0400811 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400812 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813
Geoff Lang5aad9672014-09-08 11:10:42 -0400814 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815
Geoff Lang5aad9672014-09-08 11:10:42 -0400816 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400817 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400818
819 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820}
821
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500822Error Context::queryCounter(GLuint id, GLenum target)
823{
824 ASSERT(target == GL_TIMESTAMP_EXT);
825
826 Query *queryObject = getQuery(id, true, target);
827 ASSERT(queryObject);
828
829 return queryObject->queryCounter();
830}
831
832void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
833{
834 switch (pname)
835 {
836 case GL_CURRENT_QUERY_EXT:
837 params[0] = getState().getActiveQueryId(target);
838 break;
839 case GL_QUERY_COUNTER_BITS_EXT:
840 switch (target)
841 {
842 case GL_TIME_ELAPSED_EXT:
843 params[0] = getExtensions().queryCounterBitsTimeElapsed;
844 break;
845 case GL_TIMESTAMP_EXT:
846 params[0] = getExtensions().queryCounterBitsTimestamp;
847 break;
848 default:
849 UNREACHABLE();
850 params[0] = 0;
851 break;
852 }
853 break;
854 default:
855 UNREACHABLE();
856 return;
857 }
858}
859
860Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
861{
862 return GetQueryObjectParameter(this, id, pname, params);
863}
864
865Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
866{
867 return GetQueryObjectParameter(this, id, pname, params);
868}
869
870Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
871{
872 return GetQueryObjectParameter(this, id, pname, params);
873}
874
875Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
876{
877 return GetQueryObjectParameter(this, id, pname, params);
878}
879
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500880Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000881{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500882 auto framebufferIt = mFramebufferMap.find(handle);
883 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884}
885
Jamie Madill33dc8432013-07-26 11:55:05 -0400886FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000887{
Jamie Madill33dc8432013-07-26 11:55:05 -0400888 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000889
Jamie Madill33dc8432013-07-26 11:55:05 -0400890 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000891 {
892 return NULL;
893 }
894 else
895 {
896 return fence->second;
897 }
898}
899
900Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
901{
902 QueryMap::iterator query = mQueryMap.find(handle);
903
904 if (query == mQueryMap.end())
905 {
906 return NULL;
907 }
908 else
909 {
910 if (!query->second && create)
911 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700912 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913 query->second->addRef();
914 }
915 return query->second;
916 }
917}
918
Geoff Lang70d0f492015-12-10 17:45:46 -0500919Query *Context::getQuery(GLuint handle) const
920{
921 auto iter = mQueryMap.find(handle);
922 return (iter != mQueryMap.end()) ? iter->second : nullptr;
923}
924
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500925Texture *Context::getTargetTexture(GLenum target) const
926{
Geoff Lang691e58c2014-12-19 17:03:25 -0500927 ASSERT(ValidTextureTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500928 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000929}
930
Geoff Lang76b10c92014-09-05 16:28:14 -0400931Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000932{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500933 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000934}
935
Geoff Lang492a7e42014-11-05 13:27:06 -0500936Compiler *Context::getCompiler() const
937{
938 return mCompiler;
939}
940
Jamie Madill893ab082014-05-16 16:56:10 -0400941void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942{
943 switch (pname)
944 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000945 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000946 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400948 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400949 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jamie Madill893ab082014-05-16 16:56:10 -0400953void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Shannon Woods53a94a82014-06-24 15:20:36 -0400955 // Queries about context capabilities and maximums are answered by Context.
956 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957 switch (pname)
958 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400960 params[0] = mCaps.minAliasedLineWidth;
961 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962 break;
963 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400964 params[0] = mCaps.minAliasedPointSize;
965 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000967 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400968 ASSERT(mExtensions.textureFilterAnisotropic);
969 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000970 break;
Geoff Lange6d4e122015-06-29 13:33:55 -0400971 case GL_MAX_TEXTURE_LOD_BIAS:
972 *params = mCaps.maxLODBias;
973 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400975 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400976 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill893ab082014-05-16 16:56:10 -0400980void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Shannon Woods53a94a82014-06-24 15:20:36 -0400982 // Queries about context capabilities and maximums are answered by Context.
983 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +0000984
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985 switch (pname)
986 {
Geoff Lang301d1612014-07-09 10:34:37 -0400987 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
988 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
989 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -0400990 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
991 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
992 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -0400993 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
994 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
995 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -0400996 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400997 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
998 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
999 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001000 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001001 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1003 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1004 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1005 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001006 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1007 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001008 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1009 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001010 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001011 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1012 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1013 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1014 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001015 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1016 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001017 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1018 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001019 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1020 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1021 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001022 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1023 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1024 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001025 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026 case GL_MAX_VIEWPORT_DIMS:
1027 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001028 params[0] = mCaps.maxViewportWidth;
1029 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030 }
1031 break;
1032 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001033 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001034 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1036 *params = mResetStrategy;
1037 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001038 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001039 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001041 case GL_SHADER_BINARY_FORMATS:
1042 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1043 break;
1044 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001045 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001046 break;
1047 case GL_PROGRAM_BINARY_FORMATS:
1048 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001049 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001050 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001051 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001052 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001053
1054 // GL_KHR_debug
1055 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1056 *params = mExtensions.maxDebugMessageLength;
1057 break;
1058 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1059 *params = mExtensions.maxDebugLoggedMessages;
1060 break;
1061 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1062 *params = mExtensions.maxDebugGroupStackDepth;
1063 break;
1064 case GL_MAX_LABEL_LENGTH:
1065 *params = mExtensions.maxLabelLength;
1066 break;
1067
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001068 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001069 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001070 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001071 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001072}
1073
Jamie Madill893ab082014-05-16 16:56:10 -04001074void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001075{
Shannon Woods53a94a82014-06-24 15:20:36 -04001076 // Queries about context capabilities and maximums are answered by Context.
1077 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001078 switch (pname)
1079 {
1080 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001081 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001082 break;
1083 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001084 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001085 break;
1086 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001087 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001088 break;
1089 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001090 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001091 break;
1092 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001093 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001094 break;
1095 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001096 UNREACHABLE();
1097 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001098 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001099}
1100
Geoff Lang70d0f492015-12-10 17:45:46 -05001101void Context::getPointerv(GLenum pname, void **params) const
1102{
1103 mState.getPointerv(pname, params);
1104}
1105
Shannon Woods1b2fb852013-08-19 14:28:48 -04001106bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1107{
Shannon Woods53a94a82014-06-24 15:20:36 -04001108 // Queries about context capabilities and maximums are answered by Context.
1109 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001110 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001111 // mere passthrough.
1112 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001113}
1114
1115bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1116{
Shannon Woods53a94a82014-06-24 15:20:36 -04001117 // Queries about context capabilities and maximums are answered by Context.
1118 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001119 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001120 // mere passthrough.
1121 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001122}
1123
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001124bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1125{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001126 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1127 {
1128 *type = GL_INT;
1129 *numParams = 1;
1130 return true;
1131 }
1132
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001133 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1134 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1135 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001136 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001137 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1138 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1139 // application.
1140 switch (pname)
1141 {
1142 case GL_COMPRESSED_TEXTURE_FORMATS:
1143 {
1144 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001145 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001146 }
1147 return true;
1148 case GL_PROGRAM_BINARY_FORMATS_OES:
1149 {
1150 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001151 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001152 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001153 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001154 case GL_SHADER_BINARY_FORMATS:
1155 {
1156 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001157 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001158 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001159 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001160
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001161 case GL_MAX_VERTEX_ATTRIBS:
1162 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1163 case GL_MAX_VARYING_VECTORS:
1164 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1165 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1166 case GL_MAX_TEXTURE_IMAGE_UNITS:
1167 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1168 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001169 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001170 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171 case GL_NUM_SHADER_BINARY_FORMATS:
1172 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1173 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001174 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1175 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1176 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177 case GL_RENDERBUFFER_BINDING:
1178 case GL_CURRENT_PROGRAM:
1179 case GL_PACK_ALIGNMENT:
1180 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1181 case GL_UNPACK_ALIGNMENT:
1182 case GL_GENERATE_MIPMAP_HINT:
1183 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1184 case GL_RED_BITS:
1185 case GL_GREEN_BITS:
1186 case GL_BLUE_BITS:
1187 case GL_ALPHA_BITS:
1188 case GL_DEPTH_BITS:
1189 case GL_STENCIL_BITS:
1190 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1191 case GL_CULL_FACE_MODE:
1192 case GL_FRONT_FACE:
1193 case GL_ACTIVE_TEXTURE:
1194 case GL_STENCIL_FUNC:
1195 case GL_STENCIL_VALUE_MASK:
1196 case GL_STENCIL_REF:
1197 case GL_STENCIL_FAIL:
1198 case GL_STENCIL_PASS_DEPTH_FAIL:
1199 case GL_STENCIL_PASS_DEPTH_PASS:
1200 case GL_STENCIL_BACK_FUNC:
1201 case GL_STENCIL_BACK_VALUE_MASK:
1202 case GL_STENCIL_BACK_REF:
1203 case GL_STENCIL_BACK_FAIL:
1204 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1205 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1206 case GL_DEPTH_FUNC:
1207 case GL_BLEND_SRC_RGB:
1208 case GL_BLEND_SRC_ALPHA:
1209 case GL_BLEND_DST_RGB:
1210 case GL_BLEND_DST_ALPHA:
1211 case GL_BLEND_EQUATION_RGB:
1212 case GL_BLEND_EQUATION_ALPHA:
1213 case GL_STENCIL_WRITEMASK:
1214 case GL_STENCIL_BACK_WRITEMASK:
1215 case GL_STENCIL_CLEAR_VALUE:
1216 case GL_SUBPIXEL_BITS:
1217 case GL_MAX_TEXTURE_SIZE:
1218 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1219 case GL_SAMPLE_BUFFERS:
1220 case GL_SAMPLES:
1221 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1222 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1223 case GL_TEXTURE_BINDING_2D:
1224 case GL_TEXTURE_BINDING_CUBE_MAP:
1225 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1226 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001227 {
1228 *type = GL_INT;
1229 *numParams = 1;
1230 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001231 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001232 case GL_MAX_SAMPLES_ANGLE:
1233 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001234 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001235 {
1236 *type = GL_INT;
1237 *numParams = 1;
1238 }
1239 else
1240 {
1241 return false;
1242 }
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_VIEWPORT_DIMS:
1246 {
1247 *type = GL_INT;
1248 *numParams = 2;
1249 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001250 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251 case GL_VIEWPORT:
1252 case GL_SCISSOR_BOX:
1253 {
1254 *type = GL_INT;
1255 *numParams = 4;
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_SHADER_COMPILER:
1259 case GL_SAMPLE_COVERAGE_INVERT:
1260 case GL_DEPTH_WRITEMASK:
1261 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1262 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1263 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1264 case GL_SAMPLE_COVERAGE:
1265 case GL_SCISSOR_TEST:
1266 case GL_STENCIL_TEST:
1267 case GL_DEPTH_TEST:
1268 case GL_BLEND:
1269 case GL_DITHER:
1270 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1271 {
1272 *type = GL_BOOL;
1273 *numParams = 1;
1274 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001275 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001276 case GL_COLOR_WRITEMASK:
1277 {
1278 *type = GL_BOOL;
1279 *numParams = 4;
1280 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001281 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001282 case GL_POLYGON_OFFSET_FACTOR:
1283 case GL_POLYGON_OFFSET_UNITS:
1284 case GL_SAMPLE_COVERAGE_VALUE:
1285 case GL_DEPTH_CLEAR_VALUE:
1286 case GL_LINE_WIDTH:
1287 {
1288 *type = GL_FLOAT;
1289 *numParams = 1;
1290 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001291 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001292 case GL_ALIASED_LINE_WIDTH_RANGE:
1293 case GL_ALIASED_POINT_SIZE_RANGE:
1294 case GL_DEPTH_RANGE:
1295 {
1296 *type = GL_FLOAT;
1297 *numParams = 2;
1298 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001299 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001300 case GL_COLOR_CLEAR_VALUE:
1301 case GL_BLEND_COLOR:
1302 {
1303 *type = GL_FLOAT;
1304 *numParams = 4;
1305 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001306 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001307 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001308 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001309 {
1310 return false;
1311 }
1312 *type = GL_FLOAT;
1313 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001314 return true;
1315 }
1316
Geoff Lang70d0f492015-12-10 17:45:46 -05001317 if (mExtensions.debug)
1318 {
1319 switch (pname)
1320 {
1321 case GL_DEBUG_LOGGED_MESSAGES:
1322 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1323 case GL_DEBUG_GROUP_STACK_DEPTH:
1324 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1325 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1326 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1327 case GL_MAX_LABEL_LENGTH:
1328 *type = GL_INT;
1329 *numParams = 1;
1330 return true;
1331
1332 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1333 case GL_DEBUG_OUTPUT:
1334 *type = GL_BOOL;
1335 *numParams = 1;
1336 return true;
1337 }
1338 }
1339
Austin Kinrossbc781f32015-10-26 09:27:38 -07001340 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1341 switch (pname)
1342 {
1343 case GL_PACK_ROW_LENGTH:
1344 case GL_PACK_SKIP_ROWS:
1345 case GL_PACK_SKIP_PIXELS:
1346 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1347 {
1348 return false;
1349 }
1350 *type = GL_INT;
1351 *numParams = 1;
1352 return true;
1353 case GL_UNPACK_ROW_LENGTH:
1354 case GL_UNPACK_SKIP_ROWS:
1355 case GL_UNPACK_SKIP_PIXELS:
1356 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1357 {
1358 return false;
1359 }
1360 *type = GL_INT;
1361 *numParams = 1;
1362 return true;
1363 case GL_VERTEX_ARRAY_BINDING:
1364 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1365 {
1366 return false;
1367 }
1368 *type = GL_INT;
1369 *numParams = 1;
1370 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001371 case GL_PIXEL_PACK_BUFFER_BINDING:
1372 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1373 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1374 {
1375 return false;
1376 }
1377 *type = GL_INT;
1378 *numParams = 1;
1379 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001380 }
1381
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001382 if (mClientVersion < 3)
1383 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001384 return false;
1385 }
1386
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001387 // Check for ES3.0+ parameter names
1388 switch (pname)
1389 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001390 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1391 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001392 case GL_UNIFORM_BUFFER_BINDING:
1393 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001394 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001395 case GL_COPY_READ_BUFFER_BINDING:
1396 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001397 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001398 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001399 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001400 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001401 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1402 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1403 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001404 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1405 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001406 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001407 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1408 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001409 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1410 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001411 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001412 case GL_MAJOR_VERSION:
1413 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001414 case GL_MAX_ELEMENTS_INDICES:
1415 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001416 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001417 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001418 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001419 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001420 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001421 {
1422 *type = GL_INT;
1423 *numParams = 1;
1424 }
1425 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001426
1427 case GL_MAX_ELEMENT_INDEX:
1428 case GL_MAX_UNIFORM_BLOCK_SIZE:
1429 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1430 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1431 case GL_MAX_SERVER_WAIT_TIMEOUT:
1432 {
1433 *type = GL_INT_64_ANGLEX;
1434 *numParams = 1;
1435 }
1436 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001437
1438 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001439 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001440 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001441 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001442 {
1443 *type = GL_BOOL;
1444 *numParams = 1;
1445 }
1446 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001447
1448 case GL_MAX_TEXTURE_LOD_BIAS:
1449 {
1450 *type = GL_FLOAT;
1451 *numParams = 1;
1452 }
1453 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001454 }
1455
1456 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001457}
1458
Shannon Woods1b2fb852013-08-19 14:28:48 -04001459bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1460{
1461 if (mClientVersion < 3)
1462 {
1463 return false;
1464 }
1465
1466 switch (target)
1467 {
1468 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1469 case GL_UNIFORM_BUFFER_BINDING:
1470 {
1471 *type = GL_INT;
1472 *numParams = 1;
1473 }
1474 return true;
1475 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1476 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1477 case GL_UNIFORM_BUFFER_START:
1478 case GL_UNIFORM_BUFFER_SIZE:
1479 {
1480 *type = GL_INT_64_ANGLEX;
1481 *numParams = 1;
1482 }
1483 }
1484
1485 return false;
1486}
1487
Geoff Langf6db0982015-08-25 13:04:00 -04001488Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001489{
Jamie Madill1b94d432015-08-07 13:23:23 -04001490 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001491 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001492 if (error.isError())
1493 {
1494 return error;
1495 }
1496
Geoff Langf6db0982015-08-25 13:04:00 -04001497 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001498
1499 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001500}
1501
Geoff Langf6db0982015-08-25 13:04:00 -04001502Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1503{
1504 syncRendererState();
1505 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1506 if (error.isError())
1507 {
1508 return error;
1509 }
1510
1511 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1512
1513 return Error(GL_NO_ERROR);
1514}
1515
1516Error Context::drawElements(GLenum mode,
1517 GLsizei count,
1518 GLenum type,
1519 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001520 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001521{
Jamie Madill1b94d432015-08-07 13:23:23 -04001522 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001523 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1524}
1525
1526Error Context::drawElementsInstanced(GLenum mode,
1527 GLsizei count,
1528 GLenum type,
1529 const GLvoid *indices,
1530 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001531 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001532{
1533 syncRendererState();
1534 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1535 indexRange);
1536}
1537
1538Error Context::drawRangeElements(GLenum mode,
1539 GLuint start,
1540 GLuint end,
1541 GLsizei count,
1542 GLenum type,
1543 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001544 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001545{
1546 syncRendererState();
1547 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1548 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001549}
1550
Geoff Lang129753a2015-01-09 16:52:09 -05001551Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001552{
Geoff Lang129753a2015-01-09 16:52:09 -05001553 return mRenderer->flush();
1554}
1555
1556Error Context::finish()
1557{
1558 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001559}
1560
Austin Kinross6ee1e782015-05-29 17:05:37 -07001561void Context::insertEventMarker(GLsizei length, const char *marker)
1562{
1563 ASSERT(mRenderer);
1564 mRenderer->insertEventMarker(length, marker);
1565}
1566
1567void Context::pushGroupMarker(GLsizei length, const char *marker)
1568{
1569 ASSERT(mRenderer);
1570 mRenderer->pushGroupMarker(length, marker);
1571}
1572
1573void Context::popGroupMarker()
1574{
1575 ASSERT(mRenderer);
1576 mRenderer->popGroupMarker();
1577}
1578
Geoff Langda5777c2014-07-11 09:52:58 -04001579void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001580{
Geoff Langda5777c2014-07-11 09:52:58 -04001581 if (error.isError())
1582 {
1583 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001584
1585 if (!error.getMessage().empty())
1586 {
1587 auto &debug = mState.getDebug();
1588 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1589 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1590 }
Geoff Langda5777c2014-07-11 09:52:58 -04001591 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001592}
1593
1594// Get one of the recorded errors and clear its flag, if any.
1595// [OpenGL ES 2.0.24] section 2.5 page 13.
1596GLenum Context::getError()
1597{
Geoff Langda5777c2014-07-11 09:52:58 -04001598 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001599 {
Geoff Langda5777c2014-07-11 09:52:58 -04001600 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001601 }
Geoff Langda5777c2014-07-11 09:52:58 -04001602 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001603 {
Geoff Langda5777c2014-07-11 09:52:58 -04001604 GLenum error = *mErrors.begin();
1605 mErrors.erase(mErrors.begin());
1606 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001608}
1609
1610GLenum Context::getResetStatus()
1611{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001612 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001613 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001615 // mResetStatus will be set by the markContextLost callback
1616 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001617 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001618 {
1619 mRenderer->notifyDeviceLost();
1620 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001621 }
1622
1623 GLenum status = mResetStatus;
1624
1625 if (mResetStatus != GL_NO_ERROR)
1626 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001627 ASSERT(mContextLost);
1628
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001629 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630 {
1631 mResetStatus = GL_NO_ERROR;
1632 }
1633 }
Jamie Madill893ab082014-05-16 16:56:10 -04001634
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001635 return status;
1636}
1637
1638bool Context::isResetNotificationEnabled()
1639{
1640 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1641}
1642
Corentin Walleze3b10e82015-05-20 11:06:25 -04001643const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001644{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001645 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001646}
1647
1648EGLenum Context::getClientType() const
1649{
1650 return mClientType;
1651}
1652
1653EGLenum Context::getRenderBuffer() const
1654{
Corentin Wallez37c39792015-08-20 14:19:46 -04001655 auto framebufferIt = mFramebufferMap.find(0);
1656 if (framebufferIt != mFramebufferMap.end())
1657 {
1658 const Framebuffer *framebuffer = framebufferIt->second;
1659 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1660
1661 ASSERT(backAttachment != nullptr);
1662 return backAttachment->getSurface()->getRenderBuffer();
1663 }
1664 else
1665 {
1666 return EGL_NONE;
1667 }
Régis Fénéon83107972015-02-05 12:57:44 +01001668}
1669
Geoff Lang36167ab2015-12-07 10:27:14 -05001670void Context::checkVertexArrayAllocation(GLuint vertexArray)
1671{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001672 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001673 if (!getVertexArray(vertexArray))
1674 {
1675 VertexArray *vertexArrayObject =
1676 new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
1677 mVertexArrayMap[vertexArray] = vertexArrayObject;
1678 }
1679}
1680
1681void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
1682{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001683 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001684 if (!getTransformFeedback(transformFeedback))
1685 {
1686 TransformFeedback *transformFeedbackObject =
1687 new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps);
1688 transformFeedbackObject->addRef();
1689 mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
1690 }
1691}
1692
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001693Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1694{
1695 // Can be called from Bind without a prior call to Gen.
1696 auto framebufferIt = mFramebufferMap.find(framebuffer);
1697 bool neverCreated = framebufferIt == mFramebufferMap.end();
1698 if (neverCreated || framebufferIt->second == nullptr)
1699 {
1700 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1701 if (neverCreated)
1702 {
1703 mFramebufferHandleAllocator.reserve(framebuffer);
1704 mFramebufferMap[framebuffer] = newFBO;
1705 return newFBO;
1706 }
1707
1708 framebufferIt->second = newFBO;
1709 }
1710
1711 return framebufferIt->second;
1712}
1713
Geoff Lang36167ab2015-12-07 10:27:14 -05001714bool Context::isVertexArrayGenerated(GLuint vertexArray)
1715{
1716 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1717}
1718
1719bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1720{
1721 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1722}
1723
Shannon Woods53a94a82014-06-24 15:20:36 -04001724void Context::detachTexture(GLuint texture)
1725{
1726 // Simple pass-through to State's detachTexture method, as textures do not require
1727 // allocation map management either here or in the resource manager at detach time.
1728 // Zero textures are held by the Context, and we don't attempt to request them from
1729 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001730 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001731}
1732
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001733void Context::detachBuffer(GLuint buffer)
1734{
Yuly Novikov5807a532015-12-03 13:01:22 -05001735 // Simple pass-through to State's detachBuffer method, since
1736 // only buffer attachments to container objects that are bound to the current context
1737 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001738
Yuly Novikov5807a532015-12-03 13:01:22 -05001739 // [OpenGL ES 3.2] section 5.1.2 page 45:
1740 // Attachments to unbound container objects, such as
1741 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1742 // are not affected and continue to act as references on the deleted object
1743 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001744}
1745
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001746void Context::detachFramebuffer(GLuint framebuffer)
1747{
Shannon Woods53a94a82014-06-24 15:20:36 -04001748 // Framebuffer detachment is handled by Context, because 0 is a valid
1749 // Framebuffer object, and a pointer to it must be passed from Context
1750 // to State at binding time.
1751
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001752 // [OpenGL ES 2.0.24] section 4.4 page 107:
1753 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1754 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1755
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001756 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001757 {
1758 bindReadFramebuffer(0);
1759 }
1760
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001761 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001762 {
1763 bindDrawFramebuffer(0);
1764 }
1765}
1766
1767void Context::detachRenderbuffer(GLuint renderbuffer)
1768{
Shannon Woods53a94a82014-06-24 15:20:36 -04001769 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001770}
1771
Jamie Madill57a89722013-07-02 11:57:03 -04001772void Context::detachVertexArray(GLuint vertexArray)
1773{
Jamie Madill77a72f62015-04-14 11:18:32 -04001774 // Vertex array detachment is handled by Context, because 0 is a valid
1775 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001776 // binding time.
1777
Jamie Madill57a89722013-07-02 11:57:03 -04001778 // [OpenGL ES 3.0.2] section 2.10 page 43:
1779 // If a vertex array object that is currently bound is deleted, the binding
1780 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001781 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001782 {
1783 bindVertexArray(0);
1784 }
1785}
1786
Geoff Langc8058452014-02-03 12:04:11 -05001787void Context::detachTransformFeedback(GLuint transformFeedback)
1788{
Shannon Woods53a94a82014-06-24 15:20:36 -04001789 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001790}
1791
Jamie Madilldc356042013-07-19 16:36:57 -04001792void Context::detachSampler(GLuint sampler)
1793{
Shannon Woods53a94a82014-06-24 15:20:36 -04001794 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001795}
1796
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001797void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1798{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001799 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001800}
1801
Jamie Madille29d1672013-07-19 16:36:57 -04001802void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1803{
1804 mResourceManager->checkSamplerAllocation(sampler);
1805
1806 Sampler *samplerObject = getSampler(sampler);
1807 ASSERT(samplerObject);
1808
Geoff Lang69cce582015-09-17 13:20:36 -04001809 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001810 switch (pname)
1811 {
Geoff Lang69cce582015-09-17 13:20:36 -04001812 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1813 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1814 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1815 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1816 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1817 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1818 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1819 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1820 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1821 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1822 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001823 }
Geoff Lang69cce582015-09-17 13:20:36 -04001824 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001825}
1826
1827void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1828{
1829 mResourceManager->checkSamplerAllocation(sampler);
1830
1831 Sampler *samplerObject = getSampler(sampler);
1832 ASSERT(samplerObject);
1833
Geoff Lang69cce582015-09-17 13:20:36 -04001834 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001835 switch (pname)
1836 {
Geoff Lang69cce582015-09-17 13:20:36 -04001837 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1838 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1839 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1840 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1841 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1842 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1843 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1844 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1845 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1846 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1847 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001848 }
Geoff Lang69cce582015-09-17 13:20:36 -04001849 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001850}
1851
Jamie Madill9675b802013-07-19 16:36:59 -04001852GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1853{
1854 mResourceManager->checkSamplerAllocation(sampler);
1855
1856 Sampler *samplerObject = getSampler(sampler);
1857 ASSERT(samplerObject);
1858
Geoff Lang69cce582015-09-17 13:20:36 -04001859 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001860 switch (pname)
1861 {
Geoff Lang69cce582015-09-17 13:20:36 -04001862 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1863 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1864 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1865 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1866 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1867 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1868 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
1869 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
1870 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1871 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1872 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001873 }
Geoff Lang69cce582015-09-17 13:20:36 -04001874 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001875}
1876
1877GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1878{
1879 mResourceManager->checkSamplerAllocation(sampler);
1880
1881 Sampler *samplerObject = getSampler(sampler);
1882 ASSERT(samplerObject);
1883
Geoff Lang69cce582015-09-17 13:20:36 -04001884 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001885 switch (pname)
1886 {
Geoff Lang69cce582015-09-17 13:20:36 -04001887 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1888 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1889 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1890 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1891 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1892 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1893 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1894 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1895 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1896 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1897 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001898 }
Geoff Lang69cce582015-09-17 13:20:36 -04001899 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001900}
1901
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001902void Context::initRendererString()
1903{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001904 std::ostringstream rendererString;
1905 rendererString << "ANGLE (";
1906 rendererString << mRenderer->getRendererDescription();
1907 rendererString << ")";
1908
Geoff Langcec35902014-04-16 10:52:36 -04001909 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001910}
1911
Geoff Langc0b9ef42014-07-02 10:02:37 -04001912const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001913{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001914 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001915}
1916
Geoff Langcec35902014-04-16 10:52:36 -04001917void Context::initExtensionStrings()
1918{
Geoff Lang493daf52014-07-03 13:38:44 -04001919 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001920
Geoff Langc0b9ef42014-07-02 10:02:37 -04001921 std::ostringstream combinedStringStream;
1922 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1923 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001924}
1925
Geoff Langc0b9ef42014-07-02 10:02:37 -04001926const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001927{
1928 return mExtensionString;
1929}
1930
Geoff Langc0b9ef42014-07-02 10:02:37 -04001931const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04001932{
1933 return mExtensionStrings[idx];
1934}
1935
1936size_t Context::getExtensionStringCount() const
1937{
1938 return mExtensionStrings.size();
1939}
1940
Geoff Lang493daf52014-07-03 13:38:44 -04001941void Context::initCaps(GLuint clientVersion)
1942{
1943 mCaps = mRenderer->getRendererCaps();
1944
1945 mExtensions = mRenderer->getRendererExtensions();
1946
Austin Kinross02df7962015-07-01 10:03:42 -07001947 mLimitations = mRenderer->getRendererLimitations();
1948
Geoff Lang493daf52014-07-03 13:38:44 -04001949 if (clientVersion < 3)
1950 {
1951 // Disable ES3+ extensions
1952 mExtensions.colorBufferFloat = false;
1953 }
1954
1955 if (clientVersion > 2)
1956 {
1957 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
1958 //mExtensions.sRGB = false;
1959 }
1960
Geoff Lang70d0f492015-12-10 17:45:46 -05001961 // Explicitly enable GL_KHR_debug
1962 mExtensions.debug = true;
1963 mExtensions.maxDebugMessageLength = 1024;
1964 mExtensions.maxDebugLoggedMessages = 1024;
1965 mExtensions.maxDebugGroupStackDepth = 1024;
1966 mExtensions.maxLabelLength = 1024;
1967
Geoff Lang301d1612014-07-09 10:34:37 -04001968 // Apply implementation limits
1969 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04001970 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
1971 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
1972
1973 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04001974
Geoff Lang900013c2014-07-07 11:32:19 -04001975 mCaps.compressedTextureFormats.clear();
1976
Geoff Lang493daf52014-07-03 13:38:44 -04001977 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
1978 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
1979 {
1980 GLenum format = i->first;
1981 TextureCaps formatCaps = i->second;
1982
Geoff Lang5d601382014-07-22 15:14:06 -04001983 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04001984
Geoff Lang0d8b7242015-09-09 14:56:53 -04001985 // Update the format caps based on the client version and extensions.
1986 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
1987 // ES3.
1988 formatCaps.texturable =
1989 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
1990 formatCaps.renderable =
1991 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
1992 formatCaps.filterable =
1993 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04001994
1995 // OpenGL ES does not support multisampling with integer formats
1996 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04001997 {
Geoff Langd87878e2014-09-19 15:42:59 -04001998 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04001999 }
Geoff Langd87878e2014-09-19 15:42:59 -04002000
2001 if (formatCaps.texturable && formatInfo.compressed)
2002 {
2003 mCaps.compressedTextureFormats.push_back(format);
2004 }
2005
2006 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002007 }
2008}
2009
Jamie Madill1b94d432015-08-07 13:23:23 -04002010void Context::syncRendererState()
2011{
2012 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002013 mRenderer->syncState(mState, dirtyBits);
2014 mState.clearDirtyBits();
2015 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002016}
2017
2018void Context::syncRendererState(const State::DirtyBits &bitMask)
2019{
2020 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002021 mRenderer->syncState(mState, dirtyBits);
2022 mState.clearDirtyBits(dirtyBits);
2023
2024 // TODO(jmadill): Filter objects by bitMask somehow?
2025 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002026}
Jamie Madillc29968b2016-01-20 11:17:23 -05002027
2028void Context::blitFramebuffer(GLint srcX0,
2029 GLint srcY0,
2030 GLint srcX1,
2031 GLint srcY1,
2032 GLint dstX0,
2033 GLint dstY0,
2034 GLint dstX1,
2035 GLint dstY1,
2036 GLbitfield mask,
2037 GLenum filter)
2038{
2039 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2040 ASSERT(readFramebuffer);
2041
2042 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2043 ASSERT(drawFramebuffer);
2044
2045 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2046 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2047
2048 syncRendererState(mState.blitStateBitMask());
2049
2050 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2051 if (error.isError())
2052 {
2053 recordError(error);
2054 return;
2055 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002056}
Jamie Madillc29968b2016-01-20 11:17:23 -05002057
2058void Context::clear(GLbitfield mask)
2059{
2060 // Sync the clear state
2061 syncRendererState(mState.clearStateBitMask());
2062
2063 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2064 if (error.isError())
2065 {
2066 recordError(error);
2067 }
2068}
2069
2070void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2071{
2072 // Sync the clear state
2073 syncRendererState(mState.clearStateBitMask());
2074
2075 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2076 if (error.isError())
2077 {
2078 recordError(error);
2079 }
2080}
2081
2082void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2083{
2084 // Sync the clear state
2085 syncRendererState(mState.clearStateBitMask());
2086
2087 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2088 if (error.isError())
2089 {
2090 recordError(error);
2091 }
2092}
2093
2094void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2095{
2096 // Sync the clear state
2097 syncRendererState(mState.clearStateBitMask());
2098
2099 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2100 if (error.isError())
2101 {
2102 recordError(error);
2103 }
2104}
2105
2106void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2107{
2108 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2109 ASSERT(framebufferObject);
2110
2111 // If a buffer is not present, the clear has no effect
2112 if (framebufferObject->getDepthbuffer() == nullptr &&
2113 framebufferObject->getStencilbuffer() == nullptr)
2114 {
2115 return;
2116 }
2117
2118 // Sync the clear state
2119 syncRendererState(mState.clearStateBitMask());
2120
2121 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2122 if (error.isError())
2123 {
2124 recordError(error);
2125 }
2126}
2127
2128void Context::readPixels(GLint x,
2129 GLint y,
2130 GLsizei width,
2131 GLsizei height,
2132 GLenum format,
2133 GLenum type,
2134 GLvoid *pixels)
2135{
2136 // Sync pack state
2137 syncRendererState(mState.packStateBitMask());
2138
2139 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2140 ASSERT(framebufferObject);
2141
2142 Rectangle area(x, y, width, height);
2143 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2144 if (error.isError())
2145 {
2146 recordError(error);
2147 }
2148}
2149
2150void Context::copyTexImage2D(GLenum target,
2151 GLint level,
2152 GLenum internalformat,
2153 GLint x,
2154 GLint y,
2155 GLsizei width,
2156 GLsizei height,
2157 GLint border)
2158{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002159 // Only sync the read FBO
2160 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2161
Jamie Madillc29968b2016-01-20 11:17:23 -05002162 Rectangle sourceArea(x, y, width, height);
2163
2164 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2165 Texture *texture =
2166 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2167 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2168 if (error.isError())
2169 {
2170 recordError(error);
2171 }
2172}
2173
2174void Context::copyTexSubImage2D(GLenum target,
2175 GLint level,
2176 GLint xoffset,
2177 GLint yoffset,
2178 GLint x,
2179 GLint y,
2180 GLsizei width,
2181 GLsizei height)
2182{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002183 // Only sync the read FBO
2184 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2185
Jamie Madillc29968b2016-01-20 11:17:23 -05002186 Offset destOffset(xoffset, yoffset, 0);
2187 Rectangle sourceArea(x, y, width, height);
2188
2189 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2190 Texture *texture =
2191 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2192 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2193 if (error.isError())
2194 {
2195 recordError(error);
2196 }
2197}
2198
2199void Context::copyTexSubImage3D(GLenum target,
2200 GLint level,
2201 GLint xoffset,
2202 GLint yoffset,
2203 GLint zoffset,
2204 GLint x,
2205 GLint y,
2206 GLsizei width,
2207 GLsizei height)
2208{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002209 // Only sync the read FBO
2210 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2211
Jamie Madillc29968b2016-01-20 11:17:23 -05002212 Offset destOffset(xoffset, yoffset, zoffset);
2213 Rectangle sourceArea(x, y, width, height);
2214
2215 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2216 Texture *texture = getTargetTexture(target);
2217 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2218 if (error.isError())
2219 {
2220 recordError(error);
2221 }
2222}
2223
2224void Context::framebufferTexture2D(GLenum target,
2225 GLenum attachment,
2226 GLenum textarget,
2227 GLuint texture,
2228 GLint level)
2229{
2230 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2231 ASSERT(framebuffer);
2232
2233 if (texture != 0)
2234 {
2235 Texture *textureObj = getTexture(texture);
2236
2237 ImageIndex index = ImageIndex::MakeInvalid();
2238
2239 if (textarget == GL_TEXTURE_2D)
2240 {
2241 index = ImageIndex::Make2D(level);
2242 }
2243 else
2244 {
2245 ASSERT(IsCubeMapTextureTarget(textarget));
2246 index = ImageIndex::MakeCube(textarget, level);
2247 }
2248
2249 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2250 }
2251 else
2252 {
2253 framebuffer->resetAttachment(attachment);
2254 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002255
2256 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002257}
2258
2259void Context::framebufferRenderbuffer(GLenum target,
2260 GLenum attachment,
2261 GLenum renderbuffertarget,
2262 GLuint renderbuffer)
2263{
2264 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2265 ASSERT(framebuffer);
2266
2267 if (renderbuffer != 0)
2268 {
2269 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2270 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2271 renderbufferObject);
2272 }
2273 else
2274 {
2275 framebuffer->resetAttachment(attachment);
2276 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002277
2278 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002279}
2280
2281void Context::framebufferTextureLayer(GLenum target,
2282 GLenum attachment,
2283 GLuint texture,
2284 GLint level,
2285 GLint layer)
2286{
2287 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2288 ASSERT(framebuffer);
2289
2290 if (texture != 0)
2291 {
2292 Texture *textureObject = getTexture(texture);
2293
2294 ImageIndex index = ImageIndex::MakeInvalid();
2295
2296 if (textureObject->getTarget() == GL_TEXTURE_3D)
2297 {
2298 index = ImageIndex::Make3D(level, layer);
2299 }
2300 else
2301 {
2302 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2303 index = ImageIndex::Make2DArray(level, layer);
2304 }
2305
2306 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2307 }
2308 else
2309 {
2310 framebuffer->resetAttachment(attachment);
2311 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002312
2313 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002314}
2315
2316void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2317{
2318 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2319 ASSERT(framebuffer);
2320 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002321 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002322}
2323
2324void Context::readBuffer(GLenum mode)
2325{
2326 Framebuffer *readFBO = mState.getReadFramebuffer();
2327 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002328 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002329}
2330
2331void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2332{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002333 // Only sync the FBO
2334 mState.syncDirtyObject(target);
2335
Jamie Madillc29968b2016-01-20 11:17:23 -05002336 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2337 ASSERT(framebuffer);
2338
2339 // The specification isn't clear what should be done when the framebuffer isn't complete.
2340 // We leave it up to the framebuffer implementation to decide what to do.
2341 Error error = framebuffer->discard(numAttachments, attachments);
2342 if (error.isError())
2343 {
2344 recordError(error);
2345 }
2346}
2347
2348void Context::invalidateFramebuffer(GLenum target,
2349 GLsizei numAttachments,
2350 const GLenum *attachments)
2351{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002352 // Only sync the FBO
2353 mState.syncDirtyObject(target);
2354
Jamie Madillc29968b2016-01-20 11:17:23 -05002355 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2356 ASSERT(framebuffer);
2357
2358 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2359 {
2360 Error error = framebuffer->invalidate(numAttachments, attachments);
2361 if (error.isError())
2362 {
2363 recordError(error);
2364 return;
2365 }
2366 }
2367}
2368
2369void Context::invalidateSubFramebuffer(GLenum target,
2370 GLsizei numAttachments,
2371 const GLenum *attachments,
2372 GLint x,
2373 GLint y,
2374 GLsizei width,
2375 GLsizei height)
2376{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002377 // Only sync the FBO
2378 mState.syncDirtyObject(target);
2379
Jamie Madillc29968b2016-01-20 11:17:23 -05002380 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2381 ASSERT(framebuffer);
2382
2383 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2384 {
2385 Rectangle area(x, y, width, height);
2386 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2387 if (error.isError())
2388 {
2389 recordError(error);
2390 return;
2391 }
2392 }
2393}
2394
2395} // namespace gl