blob: 58f39a6a92184b23d4a7c51a9fa470c0a8709b9c [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
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000689void Context::bindReadFramebuffer(GLuint framebuffer)
690{
691 if (!getFramebuffer(framebuffer))
692 {
Jamie Madilld1405e52015-03-05 15:41:39 -0500693 mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000694 }
695
Shannon Woods53a94a82014-06-24 15:20:36 -0400696 mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000697}
698
699void Context::bindDrawFramebuffer(GLuint framebuffer)
700{
701 if (!getFramebuffer(framebuffer))
702 {
Jamie Madilld1405e52015-03-05 15:41:39 -0500703 mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000704 }
705
Shannon Woods53a94a82014-06-24 15:20:36 -0400706 mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000707}
708
709void Context::bindRenderbuffer(GLuint renderbuffer)
710{
711 mResourceManager->checkRenderbufferAllocation(renderbuffer);
712
Shannon Woods53a94a82014-06-24 15:20:36 -0400713 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000714}
715
Jamie Madill57a89722013-07-02 11:57:03 -0400716void Context::bindVertexArray(GLuint vertexArray)
717{
Geoff Lang36167ab2015-12-07 10:27:14 -0500718 checkVertexArrayAllocation(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400719
Shannon Woods53a94a82014-06-24 15:20:36 -0400720 mState.setVertexArrayBinding(getVertexArray(vertexArray));
Jamie Madill57a89722013-07-02 11:57:03 -0400721}
722
Jamie Madilldc356042013-07-19 16:36:57 -0400723void Context::bindSampler(GLuint textureUnit, GLuint sampler)
724{
Geoff Lang76b10c92014-09-05 16:28:14 -0400725 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madilldc356042013-07-19 16:36:57 -0400726 mResourceManager->checkSamplerAllocation(sampler);
727
Shannon Woods53a94a82014-06-24 15:20:36 -0400728 mState.setSamplerBinding(textureUnit, getSampler(sampler));
Jamie Madilldc356042013-07-19 16:36:57 -0400729}
730
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000731void Context::bindGenericUniformBuffer(GLuint buffer)
732{
733 mResourceManager->checkBufferAllocation(buffer);
734
Shannon Woods53a94a82014-06-24 15:20:36 -0400735 mState.setGenericUniformBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000736}
737
738void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000739{
740 mResourceManager->checkBufferAllocation(buffer);
741
Shannon Woods53a94a82014-06-24 15:20:36 -0400742 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000743}
744
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000745void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
746{
747 mResourceManager->checkBufferAllocation(buffer);
748
Geoff Lang045536b2015-03-27 15:17:18 -0400749 mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000750}
751
752void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000753{
754 mResourceManager->checkBufferAllocation(buffer);
755
Geoff Lang045536b2015-03-27 15:17:18 -0400756 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000757}
758
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000759void Context::bindCopyReadBuffer(GLuint buffer)
760{
761 mResourceManager->checkBufferAllocation(buffer);
762
Shannon Woods53a94a82014-06-24 15:20:36 -0400763 mState.setCopyReadBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000764}
765
766void Context::bindCopyWriteBuffer(GLuint buffer)
767{
768 mResourceManager->checkBufferAllocation(buffer);
769
Shannon Woods53a94a82014-06-24 15:20:36 -0400770 mState.setCopyWriteBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000771}
772
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000773void Context::bindPixelPackBuffer(GLuint buffer)
774{
775 mResourceManager->checkBufferAllocation(buffer);
776
Shannon Woods53a94a82014-06-24 15:20:36 -0400777 mState.setPixelPackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000778}
779
780void Context::bindPixelUnpackBuffer(GLuint buffer)
781{
782 mResourceManager->checkBufferAllocation(buffer);
783
Shannon Woods53a94a82014-06-24 15:20:36 -0400784 mState.setPixelUnpackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000785}
786
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000787void Context::useProgram(GLuint program)
788{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500789 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000790}
791
Geoff Langc8058452014-02-03 12:04:11 -0500792void Context::bindTransformFeedback(GLuint transformFeedback)
793{
Geoff Lang36167ab2015-12-07 10:27:14 -0500794 checkTransformFeedbackAllocation(transformFeedback);
795
Shannon Woods53a94a82014-06-24 15:20:36 -0400796 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
Geoff Langc8058452014-02-03 12:04:11 -0500797}
798
Geoff Lang5aad9672014-09-08 11:10:42 -0400799Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400802 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803
Geoff Lang5aad9672014-09-08 11:10:42 -0400804 // begin query
805 Error error = queryObject->begin();
806 if (error.isError())
807 {
808 return error;
809 }
810
811 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400812 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813
Geoff Lang5aad9672014-09-08 11:10:42 -0400814 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815}
816
Geoff Lang5aad9672014-09-08 11:10:42 -0400817Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000818{
Shannon Woods53a94a82014-06-24 15:20:36 -0400819 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400820 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821
Geoff Lang5aad9672014-09-08 11:10:42 -0400822 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000823
Geoff Lang5aad9672014-09-08 11:10:42 -0400824 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400825 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400826
827 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000828}
829
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500830Error Context::queryCounter(GLuint id, GLenum target)
831{
832 ASSERT(target == GL_TIMESTAMP_EXT);
833
834 Query *queryObject = getQuery(id, true, target);
835 ASSERT(queryObject);
836
837 return queryObject->queryCounter();
838}
839
840void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
841{
842 switch (pname)
843 {
844 case GL_CURRENT_QUERY_EXT:
845 params[0] = getState().getActiveQueryId(target);
846 break;
847 case GL_QUERY_COUNTER_BITS_EXT:
848 switch (target)
849 {
850 case GL_TIME_ELAPSED_EXT:
851 params[0] = getExtensions().queryCounterBitsTimeElapsed;
852 break;
853 case GL_TIMESTAMP_EXT:
854 params[0] = getExtensions().queryCounterBitsTimestamp;
855 break;
856 default:
857 UNREACHABLE();
858 params[0] = 0;
859 break;
860 }
861 break;
862 default:
863 UNREACHABLE();
864 return;
865 }
866}
867
868Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
869{
870 return GetQueryObjectParameter(this, id, pname, params);
871}
872
873Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
874{
875 return GetQueryObjectParameter(this, id, pname, params);
876}
877
878Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
879{
880 return GetQueryObjectParameter(this, id, pname, params);
881}
882
883Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
884{
885 return GetQueryObjectParameter(this, id, pname, params);
886}
887
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500888Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000889{
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500890 FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000891
892 if (framebuffer == mFramebufferMap.end())
893 {
894 return NULL;
895 }
896 else
897 {
898 return framebuffer->second;
899 }
900}
901
Jamie Madill33dc8432013-07-26 11:55:05 -0400902FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000903{
Jamie Madill33dc8432013-07-26 11:55:05 -0400904 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000905
Jamie Madill33dc8432013-07-26 11:55:05 -0400906 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000907 {
908 return NULL;
909 }
910 else
911 {
912 return fence->second;
913 }
914}
915
916Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
917{
918 QueryMap::iterator query = mQueryMap.find(handle);
919
920 if (query == mQueryMap.end())
921 {
922 return NULL;
923 }
924 else
925 {
926 if (!query->second && create)
927 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700928 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929 query->second->addRef();
930 }
931 return query->second;
932 }
933}
934
Geoff Lang70d0f492015-12-10 17:45:46 -0500935Query *Context::getQuery(GLuint handle) const
936{
937 auto iter = mQueryMap.find(handle);
938 return (iter != mQueryMap.end()) ? iter->second : nullptr;
939}
940
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500941Texture *Context::getTargetTexture(GLenum target) const
942{
Geoff Lang691e58c2014-12-19 17:03:25 -0500943 ASSERT(ValidTextureTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500944 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000945}
946
Geoff Lang76b10c92014-09-05 16:28:14 -0400947Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000948{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500949 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950}
951
Geoff Lang492a7e42014-11-05 13:27:06 -0500952Compiler *Context::getCompiler() const
953{
954 return mCompiler;
955}
956
Jamie Madill893ab082014-05-16 16:56:10 -0400957void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000958{
959 switch (pname)
960 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000961 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000962 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000963 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400964 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400965 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000967}
968
Jamie Madill893ab082014-05-16 16:56:10 -0400969void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000970{
Shannon Woods53a94a82014-06-24 15:20:36 -0400971 // Queries about context capabilities and maximums are answered by Context.
972 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000973 switch (pname)
974 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000975 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400976 params[0] = mCaps.minAliasedLineWidth;
977 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978 break;
979 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400980 params[0] = mCaps.minAliasedPointSize;
981 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000982 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000983 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400984 ASSERT(mExtensions.textureFilterAnisotropic);
985 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000986 break;
Geoff Lange6d4e122015-06-29 13:33:55 -0400987 case GL_MAX_TEXTURE_LOD_BIAS:
988 *params = mCaps.maxLODBias;
989 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400991 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400992 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000993 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000994}
995
Jamie Madill893ab082014-05-16 16:56:10 -0400996void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000997{
Shannon Woods53a94a82014-06-24 15:20:36 -0400998 // Queries about context capabilities and maximums are answered by Context.
999 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001000
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001001 switch (pname)
1002 {
Geoff Lang301d1612014-07-09 10:34:37 -04001003 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
1004 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
1005 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001006 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
1007 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1008 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001009 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
1010 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
1011 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -04001012 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001013 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
1014 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
1015 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001016 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001017 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001018 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1019 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1020 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1021 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001022 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1023 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001024 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1025 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001026 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001027 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1028 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1029 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1030 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001031 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1032 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001033 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1034 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001035 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1036 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1037 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001038 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1039 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1040 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001041 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001042 case GL_MAX_VIEWPORT_DIMS:
1043 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001044 params[0] = mCaps.maxViewportWidth;
1045 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001046 }
1047 break;
1048 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001049 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001050 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001051 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1052 *params = mResetStrategy;
1053 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001054 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001055 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001056 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001057 case GL_SHADER_BINARY_FORMATS:
1058 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1059 break;
1060 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001061 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001062 break;
1063 case GL_PROGRAM_BINARY_FORMATS:
1064 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001065 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001066 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001067 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001068 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001069
1070 // GL_KHR_debug
1071 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1072 *params = mExtensions.maxDebugMessageLength;
1073 break;
1074 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1075 *params = mExtensions.maxDebugLoggedMessages;
1076 break;
1077 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1078 *params = mExtensions.maxDebugGroupStackDepth;
1079 break;
1080 case GL_MAX_LABEL_LENGTH:
1081 *params = mExtensions.maxLabelLength;
1082 break;
1083
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001084 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001085 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001086 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001087 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088}
1089
Jamie Madill893ab082014-05-16 16:56:10 -04001090void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001091{
Shannon Woods53a94a82014-06-24 15:20:36 -04001092 // Queries about context capabilities and maximums are answered by Context.
1093 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001094 switch (pname)
1095 {
1096 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001097 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001098 break;
1099 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001100 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001101 break;
1102 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001103 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001104 break;
1105 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001106 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001107 break;
1108 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001109 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001110 break;
1111 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001112 UNREACHABLE();
1113 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001114 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001115}
1116
Geoff Lang70d0f492015-12-10 17:45:46 -05001117void Context::getPointerv(GLenum pname, void **params) const
1118{
1119 mState.getPointerv(pname, params);
1120}
1121
Shannon Woods1b2fb852013-08-19 14:28:48 -04001122bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1123{
Shannon Woods53a94a82014-06-24 15:20:36 -04001124 // Queries about context capabilities and maximums are answered by Context.
1125 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001126 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001127 // mere passthrough.
1128 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001129}
1130
1131bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1132{
Shannon Woods53a94a82014-06-24 15:20:36 -04001133 // Queries about context capabilities and maximums are answered by Context.
1134 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001135 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001136 // mere passthrough.
1137 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001138}
1139
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001140bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1141{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001142 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1143 {
1144 *type = GL_INT;
1145 *numParams = 1;
1146 return true;
1147 }
1148
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001149 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1150 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1151 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001152 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001153 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1154 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1155 // application.
1156 switch (pname)
1157 {
1158 case GL_COMPRESSED_TEXTURE_FORMATS:
1159 {
1160 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001161 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001162 }
1163 return true;
1164 case GL_PROGRAM_BINARY_FORMATS_OES:
1165 {
1166 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001167 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001169 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001170 case GL_SHADER_BINARY_FORMATS:
1171 {
1172 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001173 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001174 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001175 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001176
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001177 case GL_MAX_VERTEX_ATTRIBS:
1178 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1179 case GL_MAX_VARYING_VECTORS:
1180 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1181 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1182 case GL_MAX_TEXTURE_IMAGE_UNITS:
1183 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1184 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001185 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001186 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 case GL_NUM_SHADER_BINARY_FORMATS:
1188 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1189 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001190 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1191 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1192 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001193 case GL_RENDERBUFFER_BINDING:
1194 case GL_CURRENT_PROGRAM:
1195 case GL_PACK_ALIGNMENT:
1196 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1197 case GL_UNPACK_ALIGNMENT:
1198 case GL_GENERATE_MIPMAP_HINT:
1199 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1200 case GL_RED_BITS:
1201 case GL_GREEN_BITS:
1202 case GL_BLUE_BITS:
1203 case GL_ALPHA_BITS:
1204 case GL_DEPTH_BITS:
1205 case GL_STENCIL_BITS:
1206 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1207 case GL_CULL_FACE_MODE:
1208 case GL_FRONT_FACE:
1209 case GL_ACTIVE_TEXTURE:
1210 case GL_STENCIL_FUNC:
1211 case GL_STENCIL_VALUE_MASK:
1212 case GL_STENCIL_REF:
1213 case GL_STENCIL_FAIL:
1214 case GL_STENCIL_PASS_DEPTH_FAIL:
1215 case GL_STENCIL_PASS_DEPTH_PASS:
1216 case GL_STENCIL_BACK_FUNC:
1217 case GL_STENCIL_BACK_VALUE_MASK:
1218 case GL_STENCIL_BACK_REF:
1219 case GL_STENCIL_BACK_FAIL:
1220 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1221 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1222 case GL_DEPTH_FUNC:
1223 case GL_BLEND_SRC_RGB:
1224 case GL_BLEND_SRC_ALPHA:
1225 case GL_BLEND_DST_RGB:
1226 case GL_BLEND_DST_ALPHA:
1227 case GL_BLEND_EQUATION_RGB:
1228 case GL_BLEND_EQUATION_ALPHA:
1229 case GL_STENCIL_WRITEMASK:
1230 case GL_STENCIL_BACK_WRITEMASK:
1231 case GL_STENCIL_CLEAR_VALUE:
1232 case GL_SUBPIXEL_BITS:
1233 case GL_MAX_TEXTURE_SIZE:
1234 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1235 case GL_SAMPLE_BUFFERS:
1236 case GL_SAMPLES:
1237 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1238 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1239 case GL_TEXTURE_BINDING_2D:
1240 case GL_TEXTURE_BINDING_CUBE_MAP:
1241 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1242 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001243 {
1244 *type = GL_INT;
1245 *numParams = 1;
1246 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001247 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001248 case GL_MAX_SAMPLES_ANGLE:
1249 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001250 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001251 {
1252 *type = GL_INT;
1253 *numParams = 1;
1254 }
1255 else
1256 {
1257 return false;
1258 }
1259 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001260 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001261 case GL_MAX_VIEWPORT_DIMS:
1262 {
1263 *type = GL_INT;
1264 *numParams = 2;
1265 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001266 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001267 case GL_VIEWPORT:
1268 case GL_SCISSOR_BOX:
1269 {
1270 *type = GL_INT;
1271 *numParams = 4;
1272 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001273 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001274 case GL_SHADER_COMPILER:
1275 case GL_SAMPLE_COVERAGE_INVERT:
1276 case GL_DEPTH_WRITEMASK:
1277 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1278 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1279 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1280 case GL_SAMPLE_COVERAGE:
1281 case GL_SCISSOR_TEST:
1282 case GL_STENCIL_TEST:
1283 case GL_DEPTH_TEST:
1284 case GL_BLEND:
1285 case GL_DITHER:
1286 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1287 {
1288 *type = GL_BOOL;
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_COLOR_WRITEMASK:
1293 {
1294 *type = GL_BOOL;
1295 *numParams = 4;
1296 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001297 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001298 case GL_POLYGON_OFFSET_FACTOR:
1299 case GL_POLYGON_OFFSET_UNITS:
1300 case GL_SAMPLE_COVERAGE_VALUE:
1301 case GL_DEPTH_CLEAR_VALUE:
1302 case GL_LINE_WIDTH:
1303 {
1304 *type = GL_FLOAT;
1305 *numParams = 1;
1306 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001307 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001308 case GL_ALIASED_LINE_WIDTH_RANGE:
1309 case GL_ALIASED_POINT_SIZE_RANGE:
1310 case GL_DEPTH_RANGE:
1311 {
1312 *type = GL_FLOAT;
1313 *numParams = 2;
1314 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001315 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001316 case GL_COLOR_CLEAR_VALUE:
1317 case GL_BLEND_COLOR:
1318 {
1319 *type = GL_FLOAT;
1320 *numParams = 4;
1321 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001322 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001323 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001324 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001325 {
1326 return false;
1327 }
1328 *type = GL_FLOAT;
1329 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001330 return true;
1331 }
1332
Geoff Lang70d0f492015-12-10 17:45:46 -05001333 if (mExtensions.debug)
1334 {
1335 switch (pname)
1336 {
1337 case GL_DEBUG_LOGGED_MESSAGES:
1338 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1339 case GL_DEBUG_GROUP_STACK_DEPTH:
1340 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1341 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1342 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1343 case GL_MAX_LABEL_LENGTH:
1344 *type = GL_INT;
1345 *numParams = 1;
1346 return true;
1347
1348 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1349 case GL_DEBUG_OUTPUT:
1350 *type = GL_BOOL;
1351 *numParams = 1;
1352 return true;
1353 }
1354 }
1355
Austin Kinrossbc781f32015-10-26 09:27:38 -07001356 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1357 switch (pname)
1358 {
1359 case GL_PACK_ROW_LENGTH:
1360 case GL_PACK_SKIP_ROWS:
1361 case GL_PACK_SKIP_PIXELS:
1362 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1363 {
1364 return false;
1365 }
1366 *type = GL_INT;
1367 *numParams = 1;
1368 return true;
1369 case GL_UNPACK_ROW_LENGTH:
1370 case GL_UNPACK_SKIP_ROWS:
1371 case GL_UNPACK_SKIP_PIXELS:
1372 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1373 {
1374 return false;
1375 }
1376 *type = GL_INT;
1377 *numParams = 1;
1378 return true;
1379 case GL_VERTEX_ARRAY_BINDING:
1380 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1381 {
1382 return false;
1383 }
1384 *type = GL_INT;
1385 *numParams = 1;
1386 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001387 case GL_PIXEL_PACK_BUFFER_BINDING:
1388 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1389 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1390 {
1391 return false;
1392 }
1393 *type = GL_INT;
1394 *numParams = 1;
1395 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001396 }
1397
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001398 if (mClientVersion < 3)
1399 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001400 return false;
1401 }
1402
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001403 // Check for ES3.0+ parameter names
1404 switch (pname)
1405 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001406 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1407 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001408 case GL_UNIFORM_BUFFER_BINDING:
1409 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001410 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001411 case GL_COPY_READ_BUFFER_BINDING:
1412 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001413 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001414 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001415 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001416 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001417 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1418 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1419 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001420 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1421 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001422 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001423 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1424 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001425 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1426 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001427 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001428 case GL_MAJOR_VERSION:
1429 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001430 case GL_MAX_ELEMENTS_INDICES:
1431 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001432 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001433 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001434 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001435 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001436 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001437 {
1438 *type = GL_INT;
1439 *numParams = 1;
1440 }
1441 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001442
1443 case GL_MAX_ELEMENT_INDEX:
1444 case GL_MAX_UNIFORM_BLOCK_SIZE:
1445 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1446 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1447 case GL_MAX_SERVER_WAIT_TIMEOUT:
1448 {
1449 *type = GL_INT_64_ANGLEX;
1450 *numParams = 1;
1451 }
1452 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001453
1454 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001455 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001456 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001457 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001458 {
1459 *type = GL_BOOL;
1460 *numParams = 1;
1461 }
1462 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001463
1464 case GL_MAX_TEXTURE_LOD_BIAS:
1465 {
1466 *type = GL_FLOAT;
1467 *numParams = 1;
1468 }
1469 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001470 }
1471
1472 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001473}
1474
Shannon Woods1b2fb852013-08-19 14:28:48 -04001475bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1476{
1477 if (mClientVersion < 3)
1478 {
1479 return false;
1480 }
1481
1482 switch (target)
1483 {
1484 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1485 case GL_UNIFORM_BUFFER_BINDING:
1486 {
1487 *type = GL_INT;
1488 *numParams = 1;
1489 }
1490 return true;
1491 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1492 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1493 case GL_UNIFORM_BUFFER_START:
1494 case GL_UNIFORM_BUFFER_SIZE:
1495 {
1496 *type = GL_INT_64_ANGLEX;
1497 *numParams = 1;
1498 }
1499 }
1500
1501 return false;
1502}
1503
Geoff Langf6db0982015-08-25 13:04:00 -04001504Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001505{
Jamie Madill1b94d432015-08-07 13:23:23 -04001506 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001507 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001508 if (error.isError())
1509 {
1510 return error;
1511 }
1512
Geoff Langf6db0982015-08-25 13:04:00 -04001513 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001514
1515 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001516}
1517
Geoff Langf6db0982015-08-25 13:04:00 -04001518Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1519{
1520 syncRendererState();
1521 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1522 if (error.isError())
1523 {
1524 return error;
1525 }
1526
1527 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1528
1529 return Error(GL_NO_ERROR);
1530}
1531
1532Error Context::drawElements(GLenum mode,
1533 GLsizei count,
1534 GLenum type,
1535 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001536 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001537{
Jamie Madill1b94d432015-08-07 13:23:23 -04001538 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001539 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1540}
1541
1542Error Context::drawElementsInstanced(GLenum mode,
1543 GLsizei count,
1544 GLenum type,
1545 const GLvoid *indices,
1546 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001547 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001548{
1549 syncRendererState();
1550 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1551 indexRange);
1552}
1553
1554Error Context::drawRangeElements(GLenum mode,
1555 GLuint start,
1556 GLuint end,
1557 GLsizei count,
1558 GLenum type,
1559 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001560 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001561{
1562 syncRendererState();
1563 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1564 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001565}
1566
Geoff Lang129753a2015-01-09 16:52:09 -05001567Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001568{
Geoff Lang129753a2015-01-09 16:52:09 -05001569 return mRenderer->flush();
1570}
1571
1572Error Context::finish()
1573{
1574 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575}
1576
Austin Kinross6ee1e782015-05-29 17:05:37 -07001577void Context::insertEventMarker(GLsizei length, const char *marker)
1578{
1579 ASSERT(mRenderer);
1580 mRenderer->insertEventMarker(length, marker);
1581}
1582
1583void Context::pushGroupMarker(GLsizei length, const char *marker)
1584{
1585 ASSERT(mRenderer);
1586 mRenderer->pushGroupMarker(length, marker);
1587}
1588
1589void Context::popGroupMarker()
1590{
1591 ASSERT(mRenderer);
1592 mRenderer->popGroupMarker();
1593}
1594
Geoff Langda5777c2014-07-11 09:52:58 -04001595void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001596{
Geoff Langda5777c2014-07-11 09:52:58 -04001597 if (error.isError())
1598 {
1599 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001600
1601 if (!error.getMessage().empty())
1602 {
1603 auto &debug = mState.getDebug();
1604 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1605 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1606 }
Geoff Langda5777c2014-07-11 09:52:58 -04001607 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001608}
1609
1610// Get one of the recorded errors and clear its flag, if any.
1611// [OpenGL ES 2.0.24] section 2.5 page 13.
1612GLenum Context::getError()
1613{
Geoff Langda5777c2014-07-11 09:52:58 -04001614 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001615 {
Geoff Langda5777c2014-07-11 09:52:58 -04001616 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001617 }
Geoff Langda5777c2014-07-11 09:52:58 -04001618 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619 {
Geoff Langda5777c2014-07-11 09:52:58 -04001620 GLenum error = *mErrors.begin();
1621 mErrors.erase(mErrors.begin());
1622 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001623 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001624}
1625
1626GLenum Context::getResetStatus()
1627{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001628 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001629 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001630 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001631 // mResetStatus will be set by the markContextLost callback
1632 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001633 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001634 {
1635 mRenderer->notifyDeviceLost();
1636 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001637 }
1638
1639 GLenum status = mResetStatus;
1640
1641 if (mResetStatus != GL_NO_ERROR)
1642 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001643 ASSERT(mContextLost);
1644
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001645 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001646 {
1647 mResetStatus = GL_NO_ERROR;
1648 }
1649 }
Jamie Madill893ab082014-05-16 16:56:10 -04001650
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001651 return status;
1652}
1653
1654bool Context::isResetNotificationEnabled()
1655{
1656 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1657}
1658
Corentin Walleze3b10e82015-05-20 11:06:25 -04001659const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001660{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001661 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001662}
1663
1664EGLenum Context::getClientType() const
1665{
1666 return mClientType;
1667}
1668
1669EGLenum Context::getRenderBuffer() const
1670{
Corentin Wallez37c39792015-08-20 14:19:46 -04001671 auto framebufferIt = mFramebufferMap.find(0);
1672 if (framebufferIt != mFramebufferMap.end())
1673 {
1674 const Framebuffer *framebuffer = framebufferIt->second;
1675 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1676
1677 ASSERT(backAttachment != nullptr);
1678 return backAttachment->getSurface()->getRenderBuffer();
1679 }
1680 else
1681 {
1682 return EGL_NONE;
1683 }
Régis Fénéon83107972015-02-05 12:57:44 +01001684}
1685
Geoff Lang36167ab2015-12-07 10:27:14 -05001686void Context::checkVertexArrayAllocation(GLuint vertexArray)
1687{
1688 if (!getVertexArray(vertexArray))
1689 {
1690 VertexArray *vertexArrayObject =
1691 new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
1692 mVertexArrayMap[vertexArray] = vertexArrayObject;
1693 }
1694}
1695
1696void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
1697{
1698 if (!getTransformFeedback(transformFeedback))
1699 {
1700 TransformFeedback *transformFeedbackObject =
1701 new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps);
1702 transformFeedbackObject->addRef();
1703 mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
1704 }
1705}
1706
1707bool Context::isVertexArrayGenerated(GLuint vertexArray)
1708{
1709 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1710}
1711
1712bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1713{
1714 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1715}
1716
Shannon Woods53a94a82014-06-24 15:20:36 -04001717void Context::detachTexture(GLuint texture)
1718{
1719 // Simple pass-through to State's detachTexture method, as textures do not require
1720 // allocation map management either here or in the resource manager at detach time.
1721 // Zero textures are held by the Context, and we don't attempt to request them from
1722 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001723 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001724}
1725
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001726void Context::detachBuffer(GLuint buffer)
1727{
Yuly Novikov5807a532015-12-03 13:01:22 -05001728 // Simple pass-through to State's detachBuffer method, since
1729 // only buffer attachments to container objects that are bound to the current context
1730 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001731
Yuly Novikov5807a532015-12-03 13:01:22 -05001732 // [OpenGL ES 3.2] section 5.1.2 page 45:
1733 // Attachments to unbound container objects, such as
1734 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1735 // are not affected and continue to act as references on the deleted object
1736 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001737}
1738
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001739void Context::detachFramebuffer(GLuint framebuffer)
1740{
Shannon Woods53a94a82014-06-24 15:20:36 -04001741 // Framebuffer detachment is handled by Context, because 0 is a valid
1742 // Framebuffer object, and a pointer to it must be passed from Context
1743 // to State at binding time.
1744
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001745 // [OpenGL ES 2.0.24] section 4.4 page 107:
1746 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1747 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1748
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001749 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001750 {
1751 bindReadFramebuffer(0);
1752 }
1753
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001754 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001755 {
1756 bindDrawFramebuffer(0);
1757 }
1758}
1759
1760void Context::detachRenderbuffer(GLuint renderbuffer)
1761{
Shannon Woods53a94a82014-06-24 15:20:36 -04001762 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001763}
1764
Jamie Madill57a89722013-07-02 11:57:03 -04001765void Context::detachVertexArray(GLuint vertexArray)
1766{
Jamie Madill77a72f62015-04-14 11:18:32 -04001767 // Vertex array detachment is handled by Context, because 0 is a valid
1768 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001769 // binding time.
1770
Jamie Madill57a89722013-07-02 11:57:03 -04001771 // [OpenGL ES 3.0.2] section 2.10 page 43:
1772 // If a vertex array object that is currently bound is deleted, the binding
1773 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001774 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001775 {
1776 bindVertexArray(0);
1777 }
1778}
1779
Geoff Langc8058452014-02-03 12:04:11 -05001780void Context::detachTransformFeedback(GLuint transformFeedback)
1781{
Shannon Woods53a94a82014-06-24 15:20:36 -04001782 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001783}
1784
Jamie Madilldc356042013-07-19 16:36:57 -04001785void Context::detachSampler(GLuint sampler)
1786{
Shannon Woods53a94a82014-06-24 15:20:36 -04001787 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001788}
1789
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001790void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1791{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001792 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001793}
1794
Jamie Madille29d1672013-07-19 16:36:57 -04001795void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1796{
1797 mResourceManager->checkSamplerAllocation(sampler);
1798
1799 Sampler *samplerObject = getSampler(sampler);
1800 ASSERT(samplerObject);
1801
Geoff Lang69cce582015-09-17 13:20:36 -04001802 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001803 switch (pname)
1804 {
Geoff Lang69cce582015-09-17 13:20:36 -04001805 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1806 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1807 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1808 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1809 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1810 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1811 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1812 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1813 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1814 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1815 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001816 }
Geoff Lang69cce582015-09-17 13:20:36 -04001817 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001818}
1819
1820void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1821{
1822 mResourceManager->checkSamplerAllocation(sampler);
1823
1824 Sampler *samplerObject = getSampler(sampler);
1825 ASSERT(samplerObject);
1826
Geoff Lang69cce582015-09-17 13:20:36 -04001827 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001828 switch (pname)
1829 {
Geoff Lang69cce582015-09-17 13:20:36 -04001830 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1831 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1832 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1833 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1834 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1835 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1836 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1837 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1838 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1839 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1840 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001841 }
Geoff Lang69cce582015-09-17 13:20:36 -04001842 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001843}
1844
Jamie Madill9675b802013-07-19 16:36:59 -04001845GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1846{
1847 mResourceManager->checkSamplerAllocation(sampler);
1848
1849 Sampler *samplerObject = getSampler(sampler);
1850 ASSERT(samplerObject);
1851
Geoff Lang69cce582015-09-17 13:20:36 -04001852 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001853 switch (pname)
1854 {
Geoff Lang69cce582015-09-17 13:20:36 -04001855 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1856 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1857 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1858 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1859 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1860 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1861 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
1862 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
1863 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1864 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1865 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001866 }
Geoff Lang69cce582015-09-17 13:20:36 -04001867 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001868}
1869
1870GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1871{
1872 mResourceManager->checkSamplerAllocation(sampler);
1873
1874 Sampler *samplerObject = getSampler(sampler);
1875 ASSERT(samplerObject);
1876
Geoff Lang69cce582015-09-17 13:20:36 -04001877 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001878 switch (pname)
1879 {
Geoff Lang69cce582015-09-17 13:20:36 -04001880 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1881 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1882 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1883 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1884 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1885 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1886 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1887 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1888 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1889 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1890 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001891 }
Geoff Lang69cce582015-09-17 13:20:36 -04001892 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001893}
1894
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001895void Context::initRendererString()
1896{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001897 std::ostringstream rendererString;
1898 rendererString << "ANGLE (";
1899 rendererString << mRenderer->getRendererDescription();
1900 rendererString << ")";
1901
Geoff Langcec35902014-04-16 10:52:36 -04001902 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001903}
1904
Geoff Langc0b9ef42014-07-02 10:02:37 -04001905const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001906{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001907 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001908}
1909
Geoff Langcec35902014-04-16 10:52:36 -04001910void Context::initExtensionStrings()
1911{
Geoff Lang493daf52014-07-03 13:38:44 -04001912 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001913
Geoff Langc0b9ef42014-07-02 10:02:37 -04001914 std::ostringstream combinedStringStream;
1915 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1916 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001917}
1918
Geoff Langc0b9ef42014-07-02 10:02:37 -04001919const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001920{
1921 return mExtensionString;
1922}
1923
Geoff Langc0b9ef42014-07-02 10:02:37 -04001924const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04001925{
1926 return mExtensionStrings[idx];
1927}
1928
1929size_t Context::getExtensionStringCount() const
1930{
1931 return mExtensionStrings.size();
1932}
1933
Geoff Lang493daf52014-07-03 13:38:44 -04001934void Context::initCaps(GLuint clientVersion)
1935{
1936 mCaps = mRenderer->getRendererCaps();
1937
1938 mExtensions = mRenderer->getRendererExtensions();
1939
Austin Kinross02df7962015-07-01 10:03:42 -07001940 mLimitations = mRenderer->getRendererLimitations();
1941
Geoff Lang493daf52014-07-03 13:38:44 -04001942 if (clientVersion < 3)
1943 {
1944 // Disable ES3+ extensions
1945 mExtensions.colorBufferFloat = false;
1946 }
1947
1948 if (clientVersion > 2)
1949 {
1950 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
1951 //mExtensions.sRGB = false;
1952 }
1953
Geoff Lang70d0f492015-12-10 17:45:46 -05001954 // Explicitly enable GL_KHR_debug
1955 mExtensions.debug = true;
1956 mExtensions.maxDebugMessageLength = 1024;
1957 mExtensions.maxDebugLoggedMessages = 1024;
1958 mExtensions.maxDebugGroupStackDepth = 1024;
1959 mExtensions.maxLabelLength = 1024;
1960
Geoff Lang301d1612014-07-09 10:34:37 -04001961 // Apply implementation limits
1962 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04001963 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
1964 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
1965
1966 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04001967
Geoff Lang900013c2014-07-07 11:32:19 -04001968 mCaps.compressedTextureFormats.clear();
1969
Geoff Lang493daf52014-07-03 13:38:44 -04001970 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
1971 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
1972 {
1973 GLenum format = i->first;
1974 TextureCaps formatCaps = i->second;
1975
Geoff Lang5d601382014-07-22 15:14:06 -04001976 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04001977
Geoff Lang0d8b7242015-09-09 14:56:53 -04001978 // Update the format caps based on the client version and extensions.
1979 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
1980 // ES3.
1981 formatCaps.texturable =
1982 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
1983 formatCaps.renderable =
1984 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
1985 formatCaps.filterable =
1986 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04001987
1988 // OpenGL ES does not support multisampling with integer formats
1989 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04001990 {
Geoff Langd87878e2014-09-19 15:42:59 -04001991 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04001992 }
Geoff Langd87878e2014-09-19 15:42:59 -04001993
1994 if (formatCaps.texturable && formatInfo.compressed)
1995 {
1996 mCaps.compressedTextureFormats.push_back(format);
1997 }
1998
1999 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002000 }
2001}
2002
Jamie Madill1b94d432015-08-07 13:23:23 -04002003void Context::syncRendererState()
2004{
2005 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002006 mRenderer->syncState(mState, dirtyBits);
2007 mState.clearDirtyBits();
2008 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002009}
2010
2011void Context::syncRendererState(const State::DirtyBits &bitMask)
2012{
2013 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002014 mRenderer->syncState(mState, dirtyBits);
2015 mState.clearDirtyBits(dirtyBits);
2016
2017 // TODO(jmadill): Filter objects by bitMask somehow?
2018 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002019}
Jamie Madillc29968b2016-01-20 11:17:23 -05002020
2021void Context::blitFramebuffer(GLint srcX0,
2022 GLint srcY0,
2023 GLint srcX1,
2024 GLint srcY1,
2025 GLint dstX0,
2026 GLint dstY0,
2027 GLint dstX1,
2028 GLint dstY1,
2029 GLbitfield mask,
2030 GLenum filter)
2031{
2032 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2033 ASSERT(readFramebuffer);
2034
2035 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2036 ASSERT(drawFramebuffer);
2037
2038 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2039 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2040
2041 syncRendererState(mState.blitStateBitMask());
2042
2043 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2044 if (error.isError())
2045 {
2046 recordError(error);
2047 return;
2048 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002049}
Jamie Madillc29968b2016-01-20 11:17:23 -05002050
2051void Context::clear(GLbitfield mask)
2052{
2053 // Sync the clear state
2054 syncRendererState(mState.clearStateBitMask());
2055
2056 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2057 if (error.isError())
2058 {
2059 recordError(error);
2060 }
2061}
2062
2063void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2064{
2065 // Sync the clear state
2066 syncRendererState(mState.clearStateBitMask());
2067
2068 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2069 if (error.isError())
2070 {
2071 recordError(error);
2072 }
2073}
2074
2075void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2076{
2077 // Sync the clear state
2078 syncRendererState(mState.clearStateBitMask());
2079
2080 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2081 if (error.isError())
2082 {
2083 recordError(error);
2084 }
2085}
2086
2087void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2088{
2089 // Sync the clear state
2090 syncRendererState(mState.clearStateBitMask());
2091
2092 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2093 if (error.isError())
2094 {
2095 recordError(error);
2096 }
2097}
2098
2099void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2100{
2101 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2102 ASSERT(framebufferObject);
2103
2104 // If a buffer is not present, the clear has no effect
2105 if (framebufferObject->getDepthbuffer() == nullptr &&
2106 framebufferObject->getStencilbuffer() == nullptr)
2107 {
2108 return;
2109 }
2110
2111 // Sync the clear state
2112 syncRendererState(mState.clearStateBitMask());
2113
2114 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2115 if (error.isError())
2116 {
2117 recordError(error);
2118 }
2119}
2120
2121void Context::readPixels(GLint x,
2122 GLint y,
2123 GLsizei width,
2124 GLsizei height,
2125 GLenum format,
2126 GLenum type,
2127 GLvoid *pixels)
2128{
2129 // Sync pack state
2130 syncRendererState(mState.packStateBitMask());
2131
2132 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2133 ASSERT(framebufferObject);
2134
2135 Rectangle area(x, y, width, height);
2136 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2137 if (error.isError())
2138 {
2139 recordError(error);
2140 }
2141}
2142
2143void Context::copyTexImage2D(GLenum target,
2144 GLint level,
2145 GLenum internalformat,
2146 GLint x,
2147 GLint y,
2148 GLsizei width,
2149 GLsizei height,
2150 GLint border)
2151{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002152 // Only sync the read FBO
2153 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2154
Jamie Madillc29968b2016-01-20 11:17:23 -05002155 Rectangle sourceArea(x, y, width, height);
2156
2157 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2158 Texture *texture =
2159 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2160 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2161 if (error.isError())
2162 {
2163 recordError(error);
2164 }
2165}
2166
2167void Context::copyTexSubImage2D(GLenum target,
2168 GLint level,
2169 GLint xoffset,
2170 GLint yoffset,
2171 GLint x,
2172 GLint y,
2173 GLsizei width,
2174 GLsizei height)
2175{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002176 // Only sync the read FBO
2177 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2178
Jamie Madillc29968b2016-01-20 11:17:23 -05002179 Offset destOffset(xoffset, yoffset, 0);
2180 Rectangle sourceArea(x, y, width, height);
2181
2182 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2183 Texture *texture =
2184 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2185 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2186 if (error.isError())
2187 {
2188 recordError(error);
2189 }
2190}
2191
2192void Context::copyTexSubImage3D(GLenum target,
2193 GLint level,
2194 GLint xoffset,
2195 GLint yoffset,
2196 GLint zoffset,
2197 GLint x,
2198 GLint y,
2199 GLsizei width,
2200 GLsizei height)
2201{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002202 // Only sync the read FBO
2203 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2204
Jamie Madillc29968b2016-01-20 11:17:23 -05002205 Offset destOffset(xoffset, yoffset, zoffset);
2206 Rectangle sourceArea(x, y, width, height);
2207
2208 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2209 Texture *texture = getTargetTexture(target);
2210 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2211 if (error.isError())
2212 {
2213 recordError(error);
2214 }
2215}
2216
2217void Context::framebufferTexture2D(GLenum target,
2218 GLenum attachment,
2219 GLenum textarget,
2220 GLuint texture,
2221 GLint level)
2222{
2223 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2224 ASSERT(framebuffer);
2225
2226 if (texture != 0)
2227 {
2228 Texture *textureObj = getTexture(texture);
2229
2230 ImageIndex index = ImageIndex::MakeInvalid();
2231
2232 if (textarget == GL_TEXTURE_2D)
2233 {
2234 index = ImageIndex::Make2D(level);
2235 }
2236 else
2237 {
2238 ASSERT(IsCubeMapTextureTarget(textarget));
2239 index = ImageIndex::MakeCube(textarget, level);
2240 }
2241
2242 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2243 }
2244 else
2245 {
2246 framebuffer->resetAttachment(attachment);
2247 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002248
2249 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002250}
2251
2252void Context::framebufferRenderbuffer(GLenum target,
2253 GLenum attachment,
2254 GLenum renderbuffertarget,
2255 GLuint renderbuffer)
2256{
2257 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2258 ASSERT(framebuffer);
2259
2260 if (renderbuffer != 0)
2261 {
2262 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2263 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2264 renderbufferObject);
2265 }
2266 else
2267 {
2268 framebuffer->resetAttachment(attachment);
2269 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002270
2271 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002272}
2273
2274void Context::framebufferTextureLayer(GLenum target,
2275 GLenum attachment,
2276 GLuint texture,
2277 GLint level,
2278 GLint layer)
2279{
2280 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2281 ASSERT(framebuffer);
2282
2283 if (texture != 0)
2284 {
2285 Texture *textureObject = getTexture(texture);
2286
2287 ImageIndex index = ImageIndex::MakeInvalid();
2288
2289 if (textureObject->getTarget() == GL_TEXTURE_3D)
2290 {
2291 index = ImageIndex::Make3D(level, layer);
2292 }
2293 else
2294 {
2295 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2296 index = ImageIndex::Make2DArray(level, layer);
2297 }
2298
2299 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2300 }
2301 else
2302 {
2303 framebuffer->resetAttachment(attachment);
2304 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002305
2306 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002307}
2308
2309void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2310{
2311 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2312 ASSERT(framebuffer);
2313 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002314 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002315}
2316
2317void Context::readBuffer(GLenum mode)
2318{
2319 Framebuffer *readFBO = mState.getReadFramebuffer();
2320 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002321 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002322}
2323
2324void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2325{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002326 // Only sync the FBO
2327 mState.syncDirtyObject(target);
2328
Jamie Madillc29968b2016-01-20 11:17:23 -05002329 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2330 ASSERT(framebuffer);
2331
2332 // The specification isn't clear what should be done when the framebuffer isn't complete.
2333 // We leave it up to the framebuffer implementation to decide what to do.
2334 Error error = framebuffer->discard(numAttachments, attachments);
2335 if (error.isError())
2336 {
2337 recordError(error);
2338 }
2339}
2340
2341void Context::invalidateFramebuffer(GLenum target,
2342 GLsizei numAttachments,
2343 const GLenum *attachments)
2344{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002345 // Only sync the FBO
2346 mState.syncDirtyObject(target);
2347
Jamie Madillc29968b2016-01-20 11:17:23 -05002348 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2349 ASSERT(framebuffer);
2350
2351 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2352 {
2353 Error error = framebuffer->invalidate(numAttachments, attachments);
2354 if (error.isError())
2355 {
2356 recordError(error);
2357 return;
2358 }
2359 }
2360}
2361
2362void Context::invalidateSubFramebuffer(GLenum target,
2363 GLsizei numAttachments,
2364 const GLenum *attachments,
2365 GLint x,
2366 GLint y,
2367 GLsizei width,
2368 GLsizei height)
2369{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002370 // Only sync the FBO
2371 mState.syncDirtyObject(target);
2372
Jamie Madillc29968b2016-01-20 11:17:23 -05002373 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2374 ASSERT(framebuffer);
2375
2376 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2377 {
2378 Rectangle area(x, y, width, height);
2379 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2380 if (error.isError())
2381 {
2382 recordError(error);
2383 return;
2384 }
2385 }
2386}
2387
2388} // namespace gl