blob: 8693c6fcce28bedd4410c5fd8b3dc520b7ec4af4 [file] [log] [blame]
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001//
Geoff Langeeba6e12014-02-03 13:12:30 -05002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/Context.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000011
Jamie Madillb9293972015-02-19 11:07:54 -050012#include <iterator>
13#include <sstream>
14
Geoff Lang0b7eef72014-06-12 14:10:47 -040015#include "common/platform.h"
Jamie Madillb9293972015-02-19 11:07:54 -050016#include "common/utilities.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Buffer.h"
Jamie Madillb9293972015-02-19 11:07:54 -050018#include "libANGLE/Compiler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050019#include "libANGLE/Display.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Fence.h"
21#include "libANGLE/Framebuffer.h"
22#include "libANGLE/FramebufferAttachment.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050023#include "libANGLE/Program.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050024#include "libANGLE/Query.h"
Jamie Madillb9293972015-02-19 11:07:54 -050025#include "libANGLE/Renderbuffer.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050026#include "libANGLE/ResourceManager.h"
27#include "libANGLE/Sampler.h"
Jamie Madill9dd0cf02014-11-24 11:38:51 -050028#include "libANGLE/Surface.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050029#include "libANGLE/Texture.h"
30#include "libANGLE/TransformFeedback.h"
31#include "libANGLE/VertexArray.h"
32#include "libANGLE/formatutils.h"
33#include "libANGLE/validationES.h"
34#include "libANGLE/renderer/Renderer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000035
Geoff Langf6db0982015-08-25 13:04:00 -040036namespace
37{
38
Ian Ewell3ffd78b2016-01-22 16:09:42 -050039template <typename T>
40gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params)
41{
42 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
43 ASSERT(queryObject != nullptr);
44
45 switch (pname)
46 {
47 case GL_QUERY_RESULT_EXT:
48 return queryObject->getResult(params);
49 case GL_QUERY_RESULT_AVAILABLE_EXT:
50 {
51 bool available;
52 gl::Error error = queryObject->isResultAvailable(&available);
53 if (!error.isError())
54 {
55 *params = static_cast<T>(available ? GL_TRUE : GL_FALSE);
56 }
57 return error;
58 }
59 default:
60 UNREACHABLE();
61 return gl::Error(GL_INVALID_OPERATION, "Unreachable Error");
62 }
63}
64
Geoff Langf6db0982015-08-25 13:04:00 -040065void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback)
66{
Geoff Lang1a683462015-09-29 15:09:59 -040067 if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
Geoff Langf6db0982015-08-25 13:04:00 -040068 {
69 for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount();
70 tfBufferIndex++)
71 {
72 const OffsetBindingPointer<gl::Buffer> &buffer =
73 transformFeedback->getIndexedBuffer(tfBufferIndex);
74 if (buffer.get() != nullptr)
75 {
76 buffer->onTransformFeedback();
77 }
78 }
79 }
80}
Jamie Madill46e6c7a2016-01-18 14:42:30 -050081
82// Attribute map queries.
83EGLint GetClientVersion(const egl::AttributeMap &attribs)
84{
85 return attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
86}
87
88GLenum GetResetStrategy(const egl::AttributeMap &attribs)
89{
90 EGLenum attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT,
91 EGL_NO_RESET_NOTIFICATION_EXT);
92 switch (attrib)
93 {
94 case EGL_NO_RESET_NOTIFICATION:
95 return GL_NO_RESET_NOTIFICATION_EXT;
96 case EGL_LOSE_CONTEXT_ON_RESET:
97 return GL_LOSE_CONTEXT_ON_RESET_EXT;
98 default:
99 UNREACHABLE();
100 return GL_NONE;
101 }
102}
103
104bool GetRobustAccess(const egl::AttributeMap &attribs)
105{
106 return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
107}
108
109bool GetDebug(const egl::AttributeMap &attribs)
110{
111 return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE);
112}
113
114bool GetNoError(const egl::AttributeMap &attribs)
115{
116 return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
117}
118
Geoff Langf6db0982015-08-25 13:04:00 -0400119} // anonymous namespace
120
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000121namespace gl
122{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000123
Corentin Wallez51706ea2015-08-07 14:39:22 -0400124Context::Context(const egl::Config *config,
Corentin Wallez51706ea2015-08-07 14:39:22 -0400125 const Context *shareContext,
126 rx::Renderer *renderer,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500127 const egl::AttributeMap &attribs)
128 : ValidationContext(GetClientVersion(attribs),
Jamie Madillf25855c2015-11-03 11:06:18 -0500129 mState,
130 mCaps,
131 mTextureCaps,
132 mExtensions,
133 nullptr,
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500134 mLimitations,
135 GetNoError(attribs)),
136 mCompiler(nullptr),
Jamie Madillf25855c2015-11-03 11:06:18 -0500137 mRenderer(renderer),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500138 mClientVersion(GetClientVersion(attribs)),
Corentin Walleze3b10e82015-05-20 11:06:25 -0400139 mConfig(config),
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500140 mClientType(EGL_OPENGL_ES_API),
141 mHasBeenCurrent(false),
142 mContextLost(false),
143 mResetStatus(GL_NO_ERROR),
144 mResetStrategy(GetResetStrategy(attribs)),
145 mRobustAccess(GetRobustAccess(attribs)),
146 mCurrentSurface(nullptr),
147 mResourceManager(nullptr)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000148{
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500149 ASSERT(!mRobustAccess); // Unimplemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000150
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500151 initCaps(mClientVersion);
Geoff Langc0b9ef42014-07-02 10:02:37 -0400152
Jamie Madill46e6c7a2016-01-18 14:42:30 -0500153 mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs));
Régis Fénéon83107972015-02-05 12:57:44 +0100154
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -0400156
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000157 if (shareContext != NULL)
158 {
159 mResourceManager = shareContext->mResourceManager;
160 mResourceManager->addRef();
161 }
162 else
163 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000164 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000165 }
166
Jamie Madillc185cb82015-04-28 12:39:08 -0400167 mData.resourceManager = mResourceManager;
168
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000169 // [OpenGL ES 2.0.24] section 3.7 page 83:
170 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
171 // and cube map texture state vectors respectively associated with them.
172 // In order that access to these initial textures not be lost, they are treated as texture
173 // objects all of whose names are 0.
174
Geoff Lang691e58c2014-12-19 17:03:25 -0500175 Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 0, GL_TEXTURE_2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500176 mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500177
Geoff Lang691e58c2014-12-19 17:03:25 -0500178 Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0, GL_TEXTURE_CUBE_MAP);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500179 mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
Geoff Lang76b10c92014-09-05 16:28:14 -0400180
181 if (mClientVersion >= 3)
182 {
183 // TODO: These could also be enabled via extension
Geoff Lang691e58c2014-12-19 17:03:25 -0500184 Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 0, GL_TEXTURE_3D);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500185 mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
Geoff Lang76b10c92014-09-05 16:28:14 -0400186
Geoff Lang691e58c2014-12-19 17:03:25 -0500187 Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0, GL_TEXTURE_2D_ARRAY);
Jamie Madilldedd7b92014-11-05 16:30:36 -0500188 mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
Geoff Lang76b10c92014-09-05 16:28:14 -0400189 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000190
Jamie Madille6382c32014-11-07 15:05:26 -0500191 mState.initializeZeroTextures(mZeroTextures);
192
Jamie Madill57a89722013-07-02 11:57:03 -0400193 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000194 bindArrayBuffer(0);
195 bindElementArrayBuffer(0);
Geoff Lang76b10c92014-09-05 16:28:14 -0400196
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000197 bindRenderbuffer(0);
198
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000199 bindGenericUniformBuffer(0);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400200 for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000201 {
202 bindIndexedUniformBuffer(0, i, 0, -1);
203 }
204
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000205 bindCopyReadBuffer(0);
206 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000207 bindPixelPackBuffer(0);
208 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000209
Geoff Lang1a683462015-09-29 15:09:59 -0400210 if (mClientVersion >= 3)
211 {
212 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
213 // In the initial state, a default transform feedback object is bound and treated as
214 // a transform feedback object with a name of zero. That object is bound any time
215 // BindTransformFeedback is called with id of zero
Geoff Lang1a683462015-09-29 15:09:59 -0400216 bindTransformFeedback(0);
217 }
Geoff Langc8058452014-02-03 12:04:11 -0500218
Jamie Madill83f349e2015-09-23 09:50:36 -0400219 mCompiler = new Compiler(mRenderer, getData());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000220}
221
222Context::~Context()
223{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500224 mState.reset();
Geoff Lang21329412014-12-02 20:50:30 +0000225
Corentin Wallez37c39792015-08-20 14:19:46 -0400226 for (auto framebuffer : mFramebufferMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000227 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400228 // Default framebuffer are owned by their respective Surface
Geoff Langf6227922015-09-04 11:05:47 -0400229 if (framebuffer.second != nullptr && framebuffer.second->id() != 0)
Corentin Wallez37c39792015-08-20 14:19:46 -0400230 {
231 SafeDelete(framebuffer.second);
232 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000233 }
234
Corentin Wallez80b24112015-08-25 16:41:57 -0400235 for (auto fence : mFenceNVMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000236 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400237 SafeDelete(fence.second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000238 }
239
Corentin Wallez80b24112015-08-25 16:41:57 -0400240 for (auto query : mQueryMap)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000241 {
Geoff Langf0aa8422015-09-29 15:08:34 -0400242 if (query.second != nullptr)
243 {
244 query.second->release();
245 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000246 }
247
Corentin Wallez80b24112015-08-25 16:41:57 -0400248 for (auto vertexArray : mVertexArrayMap)
Jamie Madill57a89722013-07-02 11:57:03 -0400249 {
Corentin Wallez80b24112015-08-25 16:41:57 -0400250 SafeDelete(vertexArray.second);
Jamie Madill57a89722013-07-02 11:57:03 -0400251 }
252
Corentin Wallez80b24112015-08-25 16:41:57 -0400253 for (auto transformFeedback : mTransformFeedbackMap)
Geoff Langc8058452014-02-03 12:04:11 -0500254 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500255 if (transformFeedback.second != nullptr)
256 {
257 transformFeedback.second->release();
258 }
Geoff Langc8058452014-02-03 12:04:11 -0500259 }
260
Jamie Madilldedd7b92014-11-05 16:30:36 -0500261 for (auto &zeroTexture : mZeroTextures)
Geoff Lang76b10c92014-09-05 16:28:14 -0400262 {
Jamie Madilldedd7b92014-11-05 16:30:36 -0500263 zeroTexture.second.set(NULL);
Geoff Lang76b10c92014-09-05 16:28:14 -0400264 }
265 mZeroTextures.clear();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000266
Corentin Wallez51706ea2015-08-07 14:39:22 -0400267 if (mCurrentSurface != nullptr)
268 {
269 releaseSurface();
270 }
271
Jamie Madill1e9ae072014-11-06 15:27:21 -0500272 if (mResourceManager)
273 {
274 mResourceManager->release();
275 }
Geoff Lang492a7e42014-11-05 13:27:06 -0500276
277 SafeDelete(mCompiler);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000278}
279
daniel@transgaming.comad629872012-11-28 19:32:06 +0000280void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000281{
Jamie Madill77a72f62015-04-14 11:18:32 -0400282 ASSERT(surface != nullptr);
283
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000284 if (!mHasBeenCurrent)
285 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000286 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400287 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000288
Shannon Woods53a94a82014-06-24 15:20:36 -0400289 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
290 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000291
292 mHasBeenCurrent = true;
293 }
294
Jamie Madill1b94d432015-08-07 13:23:23 -0400295 // TODO(jmadill): Rework this when we support ContextImpl
296 mState.setAllDirtyBits();
297
Corentin Wallez51706ea2015-08-07 14:39:22 -0400298 if (mCurrentSurface)
299 {
300 releaseSurface();
301 }
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000302 surface->setIsCurrent(true);
Corentin Wallez37c39792015-08-20 14:19:46 -0400303 mCurrentSurface = surface;
Jamie Madill18fdcbc2015-08-19 18:12:44 +0000304
Corentin Wallez37c39792015-08-20 14:19:46 -0400305 // Update default framebuffer, the binding of the previous default
306 // framebuffer (or lack of) will have a nullptr.
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400307 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400308 Framebuffer *newDefault = surface->getDefaultFramebuffer();
309 if (mState.getReadFramebuffer() == nullptr)
310 {
311 mState.setReadFramebufferBinding(newDefault);
312 }
313 if (mState.getDrawFramebuffer() == nullptr)
314 {
315 mState.setDrawFramebufferBinding(newDefault);
316 }
317 mFramebufferMap[0] = newDefault;
Jamie Madillc1c1cdc2015-04-30 09:42:26 -0400318 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000319}
320
Jamie Madill77a72f62015-04-14 11:18:32 -0400321void Context::releaseSurface()
322{
Corentin Wallez37c39792015-08-20 14:19:46 -0400323 ASSERT(mCurrentSurface != nullptr);
324
325 // Remove the default framebuffer
Corentin Wallez51706ea2015-08-07 14:39:22 -0400326 {
Corentin Wallez37c39792015-08-20 14:19:46 -0400327 Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer();
328 if (mState.getReadFramebuffer() == currentDefault)
329 {
330 mState.setReadFramebufferBinding(nullptr);
331 }
332 if (mState.getDrawFramebuffer() == currentDefault)
333 {
334 mState.setDrawFramebufferBinding(nullptr);
335 }
336 mFramebufferMap.erase(0);
Corentin Wallez51706ea2015-08-07 14:39:22 -0400337 }
338
Corentin Wallez51706ea2015-08-07 14:39:22 -0400339 mCurrentSurface->setIsCurrent(false);
340 mCurrentSurface = nullptr;
Jamie Madill77a72f62015-04-14 11:18:32 -0400341}
342
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000343// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000344void Context::markContextLost()
345{
346 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
347 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
348 mContextLost = true;
349}
350
351bool Context::isContextLost()
352{
353 return mContextLost;
354}
355
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000356GLuint Context::createBuffer()
357{
358 return mResourceManager->createBuffer();
359}
360
361GLuint Context::createProgram()
362{
363 return mResourceManager->createProgram();
364}
365
366GLuint Context::createShader(GLenum type)
367{
Jamie Madill006cbc52015-09-23 16:47:54 -0400368 return mResourceManager->createShader(mRenderer->getRendererLimitations(), type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000369}
370
371GLuint Context::createTexture()
372{
373 return mResourceManager->createTexture();
374}
375
376GLuint Context::createRenderbuffer()
377{
378 return mResourceManager->createRenderbuffer();
379}
380
Geoff Lang882033e2014-09-30 11:26:07 -0400381GLsync Context::createFenceSync()
Jamie Madillcd055f82013-07-26 11:55:15 -0400382{
383 GLuint handle = mResourceManager->createFenceSync();
384
Cooper Partind8e62a32015-01-29 15:21:25 -0800385 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
Jamie Madillcd055f82013-07-26 11:55:15 -0400386}
387
Jamie Madill57a89722013-07-02 11:57:03 -0400388GLuint Context::createVertexArray()
389{
Geoff Lang36167ab2015-12-07 10:27:14 -0500390 GLuint vertexArray = mVertexArrayHandleAllocator.allocate();
391 mVertexArrayMap[vertexArray] = nullptr;
392 return vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400393}
394
Jamie Madilldc356042013-07-19 16:36:57 -0400395GLuint Context::createSampler()
396{
397 return mResourceManager->createSampler();
398}
399
Geoff Langc8058452014-02-03 12:04:11 -0500400GLuint Context::createTransformFeedback()
401{
Geoff Lang36167ab2015-12-07 10:27:14 -0500402 GLuint transformFeedback = mTransformFeedbackAllocator.allocate();
403 mTransformFeedbackMap[transformFeedback] = nullptr;
404 return transformFeedback;
Geoff Langc8058452014-02-03 12:04:11 -0500405}
406
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000407// Returns an unused framebuffer name
408GLuint Context::createFramebuffer()
409{
410 GLuint handle = mFramebufferHandleAllocator.allocate();
411
412 mFramebufferMap[handle] = NULL;
413
414 return handle;
415}
416
Jamie Madill33dc8432013-07-26 11:55:05 -0400417GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000418{
Jamie Madill33dc8432013-07-26 11:55:05 -0400419 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000420
Kenneth Russellcaa549c2014-10-10 17:52:59 -0700421 mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000422
423 return handle;
424}
425
426// Returns an unused query name
427GLuint Context::createQuery()
428{
429 GLuint handle = mQueryHandleAllocator.allocate();
430
431 mQueryMap[handle] = NULL;
432
433 return handle;
434}
435
436void Context::deleteBuffer(GLuint buffer)
437{
438 if (mResourceManager->getBuffer(buffer))
439 {
440 detachBuffer(buffer);
441 }
Jamie Madill893ab082014-05-16 16:56:10 -0400442
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000443 mResourceManager->deleteBuffer(buffer);
444}
445
446void Context::deleteShader(GLuint shader)
447{
448 mResourceManager->deleteShader(shader);
449}
450
451void Context::deleteProgram(GLuint program)
452{
453 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000454}
455
456void Context::deleteTexture(GLuint texture)
457{
458 if (mResourceManager->getTexture(texture))
459 {
460 detachTexture(texture);
461 }
462
463 mResourceManager->deleteTexture(texture);
464}
465
466void Context::deleteRenderbuffer(GLuint renderbuffer)
467{
468 if (mResourceManager->getRenderbuffer(renderbuffer))
469 {
470 detachRenderbuffer(renderbuffer);
471 }
Jamie Madill893ab082014-05-16 16:56:10 -0400472
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473 mResourceManager->deleteRenderbuffer(renderbuffer);
474}
475
Jamie Madillcd055f82013-07-26 11:55:15 -0400476void Context::deleteFenceSync(GLsync fenceSync)
477{
478 // The spec specifies the underlying Fence object is not deleted until all current
479 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
480 // and since our API is currently designed for being called from a single thread, we can delete
481 // the fence immediately.
Minmin Gong794e0002015-04-07 18:31:54 -0700482 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400483}
484
Jamie Madill57a89722013-07-02 11:57:03 -0400485void Context::deleteVertexArray(GLuint vertexArray)
486{
Geoff Lang36167ab2015-12-07 10:27:14 -0500487 auto iter = mVertexArrayMap.find(vertexArray);
488 if (iter != mVertexArrayMap.end())
Geoff Lang50b3fe82015-12-08 14:49:12 +0000489 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500490 VertexArray *vertexArrayObject = iter->second;
491 if (vertexArrayObject != nullptr)
492 {
493 detachVertexArray(vertexArray);
494 delete vertexArrayObject;
495 }
Geoff Lang50b3fe82015-12-08 14:49:12 +0000496
Geoff Lang36167ab2015-12-07 10:27:14 -0500497 mVertexArrayMap.erase(iter);
498 mVertexArrayHandleAllocator.release(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400499 }
500}
501
Jamie Madilldc356042013-07-19 16:36:57 -0400502void Context::deleteSampler(GLuint sampler)
503{
504 if (mResourceManager->getSampler(sampler))
505 {
506 detachSampler(sampler);
507 }
508
509 mResourceManager->deleteSampler(sampler);
510}
511
Geoff Langc8058452014-02-03 12:04:11 -0500512void Context::deleteTransformFeedback(GLuint transformFeedback)
513{
Jamie Madill5fd0b2d2015-01-05 13:38:44 -0500514 auto iter = mTransformFeedbackMap.find(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500515 if (iter != mTransformFeedbackMap.end())
516 {
Geoff Lang36167ab2015-12-07 10:27:14 -0500517 TransformFeedback *transformFeedbackObject = iter->second;
518 if (transformFeedbackObject != nullptr)
519 {
520 detachTransformFeedback(transformFeedback);
521 transformFeedbackObject->release();
522 }
523
Geoff Lang50b3fe82015-12-08 14:49:12 +0000524 mTransformFeedbackMap.erase(iter);
Geoff Lang36167ab2015-12-07 10:27:14 -0500525 mTransformFeedbackAllocator.release(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -0500526 }
527}
528
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000529void Context::deleteFramebuffer(GLuint framebuffer)
530{
531 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
532
533 if (framebufferObject != mFramebufferMap.end())
534 {
535 detachFramebuffer(framebuffer);
536
537 mFramebufferHandleAllocator.release(framebufferObject->first);
538 delete framebufferObject->second;
539 mFramebufferMap.erase(framebufferObject);
540 }
541}
542
Jamie Madill33dc8432013-07-26 11:55:05 -0400543void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000544{
Jamie Madill33dc8432013-07-26 11:55:05 -0400545 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546
Jamie Madill33dc8432013-07-26 11:55:05 -0400547 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000548 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400549 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000550 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400551 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000552 }
553}
554
555void Context::deleteQuery(GLuint query)
556{
557 QueryMap::iterator queryObject = mQueryMap.find(query);
558 if (queryObject != mQueryMap.end())
559 {
560 mQueryHandleAllocator.release(queryObject->first);
561 if (queryObject->second)
562 {
563 queryObject->second->release();
564 }
565 mQueryMap.erase(queryObject);
566 }
567}
568
Geoff Lang70d0f492015-12-10 17:45:46 -0500569Buffer *Context::getBuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570{
571 return mResourceManager->getBuffer(handle);
572}
573
Geoff Lang48dcae72014-02-05 16:28:24 -0500574Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575{
576 return mResourceManager->getShader(handle);
577}
578
Geoff Lang48dcae72014-02-05 16:28:24 -0500579Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580{
581 return mResourceManager->getProgram(handle);
582}
583
Jamie Madill570f7c82014-07-03 10:38:54 -0400584Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000585{
586 return mResourceManager->getTexture(handle);
587}
588
Geoff Lang70d0f492015-12-10 17:45:46 -0500589Renderbuffer *Context::getRenderbuffer(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000590{
591 return mResourceManager->getRenderbuffer(handle);
592}
593
Jamie Madillcd055f82013-07-26 11:55:15 -0400594FenceSync *Context::getFenceSync(GLsync handle) const
595{
Minmin Gong794e0002015-04-07 18:31:54 -0700596 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
Jamie Madillcd055f82013-07-26 11:55:15 -0400597}
598
Jamie Madill57a89722013-07-02 11:57:03 -0400599VertexArray *Context::getVertexArray(GLuint handle) const
600{
601 auto vertexArray = mVertexArrayMap.find(handle);
Geoff Lang36167ab2015-12-07 10:27:14 -0500602 return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr;
Jamie Madill57a89722013-07-02 11:57:03 -0400603}
604
Jamie Madilldc356042013-07-19 16:36:57 -0400605Sampler *Context::getSampler(GLuint handle) const
606{
607 return mResourceManager->getSampler(handle);
608}
609
Geoff Langc8058452014-02-03 12:04:11 -0500610TransformFeedback *Context::getTransformFeedback(GLuint handle) const
611{
Geoff Lang36167ab2015-12-07 10:27:14 -0500612 auto iter = mTransformFeedbackMap.find(handle);
613 return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
Geoff Langc8058452014-02-03 12:04:11 -0500614}
615
Geoff Lang70d0f492015-12-10 17:45:46 -0500616LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
617{
618 switch (identifier)
619 {
620 case GL_BUFFER:
621 return getBuffer(name);
622 case GL_SHADER:
623 return getShader(name);
624 case GL_PROGRAM:
625 return getProgram(name);
626 case GL_VERTEX_ARRAY:
627 return getVertexArray(name);
628 case GL_QUERY:
629 return getQuery(name);
630 case GL_TRANSFORM_FEEDBACK:
631 return getTransformFeedback(name);
632 case GL_SAMPLER:
633 return getSampler(name);
634 case GL_TEXTURE:
635 return getTexture(name);
636 case GL_RENDERBUFFER:
637 return getRenderbuffer(name);
638 case GL_FRAMEBUFFER:
639 return getFramebuffer(name);
640 default:
641 UNREACHABLE();
642 return nullptr;
643 }
644}
645
646LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
647{
648 return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
649}
650
Jamie Madilldc356042013-07-19 16:36:57 -0400651bool Context::isSampler(GLuint samplerName) const
652{
653 return mResourceManager->isSampler(samplerName);
654}
655
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000656void Context::bindArrayBuffer(unsigned int buffer)
657{
658 mResourceManager->checkBufferAllocation(buffer);
659
Shannon Woods53a94a82014-06-24 15:20:36 -0400660 mState.setArrayBufferBinding(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000661}
662
663void Context::bindElementArrayBuffer(unsigned int buffer)
664{
665 mResourceManager->checkBufferAllocation(buffer);
666
Shannon Woods53a94a82014-06-24 15:20:36 -0400667 mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000668}
669
Jamie Madilldedd7b92014-11-05 16:30:36 -0500670void Context::bindTexture(GLenum target, GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500672 Texture *texture = NULL;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000673
Jamie Madilldedd7b92014-11-05 16:30:36 -0500674 if (handle == 0)
675 {
676 texture = mZeroTextures[target].get();
677 }
678 else
679 {
680 mResourceManager->checkTextureAllocation(handle, target);
681 texture = getTexture(handle);
682 }
683
684 ASSERT(texture);
685
686 mState.setSamplerTexture(target, texture);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000687}
688
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500689void Context::bindReadFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000690{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500691 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
692 mState.setReadFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000693}
694
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500695void Context::bindDrawFramebuffer(GLuint framebufferHandle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000696{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500697 Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle);
698 mState.setDrawFramebufferBinding(framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000699}
700
701void Context::bindRenderbuffer(GLuint renderbuffer)
702{
703 mResourceManager->checkRenderbufferAllocation(renderbuffer);
704
Shannon Woods53a94a82014-06-24 15:20:36 -0400705 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000706}
707
Jamie Madill57a89722013-07-02 11:57:03 -0400708void Context::bindVertexArray(GLuint vertexArray)
709{
Geoff Lang36167ab2015-12-07 10:27:14 -0500710 checkVertexArrayAllocation(vertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -0400711
Shannon Woods53a94a82014-06-24 15:20:36 -0400712 mState.setVertexArrayBinding(getVertexArray(vertexArray));
Jamie Madill57a89722013-07-02 11:57:03 -0400713}
714
Jamie Madilldc356042013-07-19 16:36:57 -0400715void Context::bindSampler(GLuint textureUnit, GLuint sampler)
716{
Geoff Lang76b10c92014-09-05 16:28:14 -0400717 ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
Jamie Madilldc356042013-07-19 16:36:57 -0400718 mResourceManager->checkSamplerAllocation(sampler);
719
Shannon Woods53a94a82014-06-24 15:20:36 -0400720 mState.setSamplerBinding(textureUnit, getSampler(sampler));
Jamie Madilldc356042013-07-19 16:36:57 -0400721}
722
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000723void Context::bindGenericUniformBuffer(GLuint buffer)
724{
725 mResourceManager->checkBufferAllocation(buffer);
726
Shannon Woods53a94a82014-06-24 15:20:36 -0400727 mState.setGenericUniformBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000728}
729
730void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000731{
732 mResourceManager->checkBufferAllocation(buffer);
733
Shannon Woods53a94a82014-06-24 15:20:36 -0400734 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000735}
736
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000737void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
738{
739 mResourceManager->checkBufferAllocation(buffer);
740
Geoff Lang045536b2015-03-27 15:17:18 -0400741 mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000742}
743
744void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000745{
746 mResourceManager->checkBufferAllocation(buffer);
747
Geoff Lang045536b2015-03-27 15:17:18 -0400748 mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000749}
750
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000751void Context::bindCopyReadBuffer(GLuint buffer)
752{
753 mResourceManager->checkBufferAllocation(buffer);
754
Shannon Woods53a94a82014-06-24 15:20:36 -0400755 mState.setCopyReadBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000756}
757
758void Context::bindCopyWriteBuffer(GLuint buffer)
759{
760 mResourceManager->checkBufferAllocation(buffer);
761
Shannon Woods53a94a82014-06-24 15:20:36 -0400762 mState.setCopyWriteBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000763}
764
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000765void Context::bindPixelPackBuffer(GLuint buffer)
766{
767 mResourceManager->checkBufferAllocation(buffer);
768
Shannon Woods53a94a82014-06-24 15:20:36 -0400769 mState.setPixelPackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000770}
771
772void Context::bindPixelUnpackBuffer(GLuint buffer)
773{
774 mResourceManager->checkBufferAllocation(buffer);
775
Shannon Woods53a94a82014-06-24 15:20:36 -0400776 mState.setPixelUnpackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000777}
778
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779void Context::useProgram(GLuint program)
780{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500781 mState.setProgram(getProgram(program));
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000782}
783
Geoff Langc8058452014-02-03 12:04:11 -0500784void Context::bindTransformFeedback(GLuint transformFeedback)
785{
Geoff Lang36167ab2015-12-07 10:27:14 -0500786 checkTransformFeedbackAllocation(transformFeedback);
787
Shannon Woods53a94a82014-06-24 15:20:36 -0400788 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
Geoff Langc8058452014-02-03 12:04:11 -0500789}
790
Geoff Lang5aad9672014-09-08 11:10:42 -0400791Error Context::beginQuery(GLenum target, GLuint query)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000793 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400794 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000795
Geoff Lang5aad9672014-09-08 11:10:42 -0400796 // begin query
797 Error error = queryObject->begin();
798 if (error.isError())
799 {
800 return error;
801 }
802
803 // set query as active for specified target only if begin succeeded
Shannon Woods53a94a82014-06-24 15:20:36 -0400804 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000805
Geoff Lang5aad9672014-09-08 11:10:42 -0400806 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000807}
808
Geoff Lang5aad9672014-09-08 11:10:42 -0400809Error Context::endQuery(GLenum target)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000810{
Shannon Woods53a94a82014-06-24 15:20:36 -0400811 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400812 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000813
Geoff Lang5aad9672014-09-08 11:10:42 -0400814 gl::Error error = queryObject->end();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000815
Geoff Lang5aad9672014-09-08 11:10:42 -0400816 // Always unbind the query, even if there was an error. This may delete the query object.
Shannon Woods53a94a82014-06-24 15:20:36 -0400817 mState.setActiveQuery(target, NULL);
Geoff Lang5aad9672014-09-08 11:10:42 -0400818
819 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000820}
821
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500822Error Context::queryCounter(GLuint id, GLenum target)
823{
824 ASSERT(target == GL_TIMESTAMP_EXT);
825
826 Query *queryObject = getQuery(id, true, target);
827 ASSERT(queryObject);
828
829 return queryObject->queryCounter();
830}
831
832void Context::getQueryiv(GLenum target, GLenum pname, GLint *params)
833{
834 switch (pname)
835 {
836 case GL_CURRENT_QUERY_EXT:
837 params[0] = getState().getActiveQueryId(target);
838 break;
839 case GL_QUERY_COUNTER_BITS_EXT:
840 switch (target)
841 {
842 case GL_TIME_ELAPSED_EXT:
843 params[0] = getExtensions().queryCounterBitsTimeElapsed;
844 break;
845 case GL_TIMESTAMP_EXT:
846 params[0] = getExtensions().queryCounterBitsTimestamp;
847 break;
848 default:
849 UNREACHABLE();
850 params[0] = 0;
851 break;
852 }
853 break;
854 default:
855 UNREACHABLE();
856 return;
857 }
858}
859
860Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params)
861{
862 return GetQueryObjectParameter(this, id, pname, params);
863}
864
865Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
866{
867 return GetQueryObjectParameter(this, id, pname, params);
868}
869
870Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
871{
872 return GetQueryObjectParameter(this, id, pname, params);
873}
874
875Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
876{
877 return GetQueryObjectParameter(this, id, pname, params);
878}
879
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500880Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000881{
Jamie Madill5bf9ff42016-02-01 11:13:03 -0500882 auto framebufferIt = mFramebufferMap.find(handle);
883 return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000884}
885
Jamie Madill33dc8432013-07-26 11:55:05 -0400886FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000887{
Jamie Madill33dc8432013-07-26 11:55:05 -0400888 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000889
Jamie Madill33dc8432013-07-26 11:55:05 -0400890 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000891 {
892 return NULL;
893 }
894 else
895 {
896 return fence->second;
897 }
898}
899
900Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
901{
902 QueryMap::iterator query = mQueryMap.find(handle);
903
904 if (query == mQueryMap.end())
905 {
906 return NULL;
907 }
908 else
909 {
910 if (!query->second && create)
911 {
Brandon Jones3b579e32014-08-08 10:54:25 -0700912 query->second = new Query(mRenderer->createQuery(type), handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913 query->second->addRef();
914 }
915 return query->second;
916 }
917}
918
Geoff Lang70d0f492015-12-10 17:45:46 -0500919Query *Context::getQuery(GLuint handle) const
920{
921 auto iter = mQueryMap.find(handle);
922 return (iter != mQueryMap.end()) ? iter->second : nullptr;
923}
924
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500925Texture *Context::getTargetTexture(GLenum target) const
926{
Geoff Lang691e58c2014-12-19 17:03:25 -0500927 ASSERT(ValidTextureTarget(this, target));
Jamie Madillc29968b2016-01-20 11:17:23 -0500928 return mState.getTargetTexture(target);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000929}
930
Geoff Lang76b10c92014-09-05 16:28:14 -0400931Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000932{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500933 return mState.getSamplerTexture(sampler, type);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000934}
935
Geoff Lang492a7e42014-11-05 13:27:06 -0500936Compiler *Context::getCompiler() const
937{
938 return mCompiler;
939}
940
Jamie Madill893ab082014-05-16 16:56:10 -0400941void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000942{
943 switch (pname)
944 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000945 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000946 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000947 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400948 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400949 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000950 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000951}
952
Jamie Madill893ab082014-05-16 16:56:10 -0400953void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000954{
Shannon Woods53a94a82014-06-24 15:20:36 -0400955 // Queries about context capabilities and maximums are answered by Context.
956 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000957 switch (pname)
958 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000959 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400960 params[0] = mCaps.minAliasedLineWidth;
961 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000962 break;
963 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400964 params[0] = mCaps.minAliasedPointSize;
965 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000966 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000967 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400968 ASSERT(mExtensions.textureFilterAnisotropic);
969 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000970 break;
Geoff Lange6d4e122015-06-29 13:33:55 -0400971 case GL_MAX_TEXTURE_LOD_BIAS:
972 *params = mCaps.maxLODBias;
973 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000974 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400975 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400976 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000977 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000978}
979
Jamie Madill893ab082014-05-16 16:56:10 -0400980void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981{
Shannon Woods53a94a82014-06-24 15:20:36 -0400982 // Queries about context capabilities and maximums are answered by Context.
983 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +0000984
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985 switch (pname)
986 {
Geoff Lang301d1612014-07-09 10:34:37 -0400987 case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
988 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
989 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
Geoff Lang3a61c322014-07-10 13:01:54 -0400990 case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
991 case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
992 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lang301d1612014-07-09 10:34:37 -0400993 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
994 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
995 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
Geoff Lange7468902015-10-02 10:46:24 -0400996 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400997 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
998 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
999 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001000 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -04001001 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -04001002 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
1003 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
1004 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
1005 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001006 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
1007 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
Geoff Lang301d1612014-07-09 10:34:37 -04001008 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
1009 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
Geoff Lang3a61c322014-07-10 13:01:54 -04001010 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
Geoff Lange6d4e122015-06-29 13:33:55 -04001011 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
1012 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
1013 case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break;
1014 case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001015 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1016 case GL_MINOR_VERSION: *params = 0; break;
Geoff Lang900013c2014-07-07 11:32:19 -04001017 case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
1018 case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
Geoff Lang05881a02014-07-10 14:05:30 -04001019 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
1020 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
1021 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001022 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1023 *params = static_cast<GLint>(mCaps.compressedTextureFormats.size());
1024 break;
Geoff Langdef624b2015-04-13 10:46:56 -04001025 case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001026 case GL_MAX_VIEWPORT_DIMS:
1027 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001028 params[0] = mCaps.maxViewportWidth;
1029 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001030 }
1031 break;
1032 case GL_COMPRESSED_TEXTURE_FORMATS:
Geoff Lang900013c2014-07-07 11:32:19 -04001033 std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001034 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001035 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1036 *params = mResetStrategy;
1037 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001038 case GL_NUM_SHADER_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001039 *params = static_cast<GLint>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001040 break;
Geoff Lang900013c2014-07-07 11:32:19 -04001041 case GL_SHADER_BINARY_FORMATS:
1042 std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
1043 break;
1044 case GL_NUM_PROGRAM_BINARY_FORMATS:
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001045 *params = static_cast<GLint>(mCaps.programBinaryFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001046 break;
1047 case GL_PROGRAM_BINARY_FORMATS:
1048 std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001049 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001050 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001051 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001052 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001053
1054 // GL_KHR_debug
1055 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1056 *params = mExtensions.maxDebugMessageLength;
1057 break;
1058 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1059 *params = mExtensions.maxDebugLoggedMessages;
1060 break;
1061 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1062 *params = mExtensions.maxDebugGroupStackDepth;
1063 break;
1064 case GL_MAX_LABEL_LENGTH:
1065 *params = mExtensions.maxLabelLength;
1066 break;
1067
Ian Ewell53f59f42016-01-28 17:36:55 -05001068 // GL_EXT_disjoint_timer_query
1069 case GL_GPU_DISJOINT_EXT:
1070 *params = mRenderer->getGPUDisjoint();
1071 break;
1072
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001073 default:
Jamie Madill48faf802014-11-06 15:27:22 -05001074 mState.getIntegerv(getData(), pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001075 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001077}
1078
Jamie Madill893ab082014-05-16 16:56:10 -04001079void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001080{
Shannon Woods53a94a82014-06-24 15:20:36 -04001081 // Queries about context capabilities and maximums are answered by Context.
1082 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001083 switch (pname)
1084 {
1085 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001086 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001087 break;
1088 case GL_MAX_UNIFORM_BLOCK_SIZE:
Geoff Lang3a61c322014-07-10 13:01:54 -04001089 *params = mCaps.maxUniformBlockSize;
Jamie Madill0fda9862013-07-19 16:36:55 -04001090 break;
1091 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001092 *params = mCaps.maxCombinedVertexUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001093 break;
1094 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang3a61c322014-07-10 13:01:54 -04001095 *params = mCaps.maxCombinedFragmentUniformComponents;
Jamie Madill0fda9862013-07-19 16:36:55 -04001096 break;
1097 case GL_MAX_SERVER_WAIT_TIMEOUT:
Geoff Lang900013c2014-07-07 11:32:19 -04001098 *params = mCaps.maxServerWaitTimeout;
Jamie Madill0fda9862013-07-19 16:36:55 -04001099 break;
Ian Ewell53f59f42016-01-28 17:36:55 -05001100
1101 // GL_EXT_disjoint_timer_query
1102 case GL_TIMESTAMP_EXT:
1103 *params = mRenderer->getTimestamp();
1104 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001105 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001106 UNREACHABLE();
1107 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001108 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001109}
1110
Geoff Lang70d0f492015-12-10 17:45:46 -05001111void Context::getPointerv(GLenum pname, void **params) const
1112{
1113 mState.getPointerv(pname, params);
1114}
1115
Shannon Woods1b2fb852013-08-19 14:28:48 -04001116bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1117{
Shannon Woods53a94a82014-06-24 15:20:36 -04001118 // Queries about context capabilities and maximums are answered by Context.
1119 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001120 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001121 // mere passthrough.
1122 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001123}
1124
1125bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1126{
Shannon Woods53a94a82014-06-24 15:20:36 -04001127 // Queries about context capabilities and maximums are answered by Context.
1128 // Queries about current GL state values are answered by State.
Jamie Madill77a72f62015-04-14 11:18:32 -04001129 // Indexed integer queries all refer to current state, so this function is a
Shannon Woods53a94a82014-06-24 15:20:36 -04001130 // mere passthrough.
1131 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001132}
1133
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001134bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1135{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001136 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1137 {
1138 *type = GL_INT;
1139 *numParams = 1;
1140 return true;
1141 }
1142
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001143 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1144 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1145 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001146 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001147 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1148 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1149 // application.
1150 switch (pname)
1151 {
1152 case GL_COMPRESSED_TEXTURE_FORMATS:
1153 {
1154 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001155 *numParams = static_cast<unsigned int>(mCaps.compressedTextureFormats.size());
Geoff Lang900013c2014-07-07 11:32:19 -04001156 }
1157 return true;
1158 case GL_PROGRAM_BINARY_FORMATS_OES:
1159 {
1160 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001161 *numParams = static_cast<unsigned int>(mCaps.programBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001162 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001163 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001164 case GL_SHADER_BINARY_FORMATS:
1165 {
1166 *type = GL_INT;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001167 *numParams = static_cast<unsigned int>(mCaps.shaderBinaryFormats.size());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001168 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001169 return true;
Jamie Madillb9293972015-02-19 11:07:54 -05001170
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001171 case GL_MAX_VERTEX_ATTRIBS:
1172 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1173 case GL_MAX_VARYING_VECTORS:
1174 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1175 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1176 case GL_MAX_TEXTURE_IMAGE_UNITS:
1177 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1178 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001179 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001180 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181 case GL_NUM_SHADER_BINARY_FORMATS:
1182 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1183 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001184 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1185 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1186 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001187 case GL_RENDERBUFFER_BINDING:
1188 case GL_CURRENT_PROGRAM:
1189 case GL_PACK_ALIGNMENT:
1190 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1191 case GL_UNPACK_ALIGNMENT:
1192 case GL_GENERATE_MIPMAP_HINT:
1193 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1194 case GL_RED_BITS:
1195 case GL_GREEN_BITS:
1196 case GL_BLUE_BITS:
1197 case GL_ALPHA_BITS:
1198 case GL_DEPTH_BITS:
1199 case GL_STENCIL_BITS:
1200 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1201 case GL_CULL_FACE_MODE:
1202 case GL_FRONT_FACE:
1203 case GL_ACTIVE_TEXTURE:
1204 case GL_STENCIL_FUNC:
1205 case GL_STENCIL_VALUE_MASK:
1206 case GL_STENCIL_REF:
1207 case GL_STENCIL_FAIL:
1208 case GL_STENCIL_PASS_DEPTH_FAIL:
1209 case GL_STENCIL_PASS_DEPTH_PASS:
1210 case GL_STENCIL_BACK_FUNC:
1211 case GL_STENCIL_BACK_VALUE_MASK:
1212 case GL_STENCIL_BACK_REF:
1213 case GL_STENCIL_BACK_FAIL:
1214 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1215 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1216 case GL_DEPTH_FUNC:
1217 case GL_BLEND_SRC_RGB:
1218 case GL_BLEND_SRC_ALPHA:
1219 case GL_BLEND_DST_RGB:
1220 case GL_BLEND_DST_ALPHA:
1221 case GL_BLEND_EQUATION_RGB:
1222 case GL_BLEND_EQUATION_ALPHA:
1223 case GL_STENCIL_WRITEMASK:
1224 case GL_STENCIL_BACK_WRITEMASK:
1225 case GL_STENCIL_CLEAR_VALUE:
1226 case GL_SUBPIXEL_BITS:
1227 case GL_MAX_TEXTURE_SIZE:
1228 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1229 case GL_SAMPLE_BUFFERS:
1230 case GL_SAMPLES:
1231 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1232 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1233 case GL_TEXTURE_BINDING_2D:
1234 case GL_TEXTURE_BINDING_CUBE_MAP:
1235 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1236 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001237 {
1238 *type = GL_INT;
1239 *numParams = 1;
1240 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001241 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001242 case GL_MAX_SAMPLES_ANGLE:
1243 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001244 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001245 {
1246 *type = GL_INT;
1247 *numParams = 1;
1248 }
1249 else
1250 {
1251 return false;
1252 }
1253 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001254 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255 case GL_MAX_VIEWPORT_DIMS:
1256 {
1257 *type = GL_INT;
1258 *numParams = 2;
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_VIEWPORT:
1262 case GL_SCISSOR_BOX:
1263 {
1264 *type = GL_INT;
1265 *numParams = 4;
1266 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001267 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001268 case GL_SHADER_COMPILER:
1269 case GL_SAMPLE_COVERAGE_INVERT:
1270 case GL_DEPTH_WRITEMASK:
1271 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1272 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1273 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1274 case GL_SAMPLE_COVERAGE:
1275 case GL_SCISSOR_TEST:
1276 case GL_STENCIL_TEST:
1277 case GL_DEPTH_TEST:
1278 case GL_BLEND:
1279 case GL_DITHER:
1280 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1281 {
1282 *type = GL_BOOL;
1283 *numParams = 1;
1284 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001285 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001286 case GL_COLOR_WRITEMASK:
1287 {
1288 *type = GL_BOOL;
1289 *numParams = 4;
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_POLYGON_OFFSET_FACTOR:
1293 case GL_POLYGON_OFFSET_UNITS:
1294 case GL_SAMPLE_COVERAGE_VALUE:
1295 case GL_DEPTH_CLEAR_VALUE:
1296 case GL_LINE_WIDTH:
1297 {
1298 *type = GL_FLOAT;
1299 *numParams = 1;
1300 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001301 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001302 case GL_ALIASED_LINE_WIDTH_RANGE:
1303 case GL_ALIASED_POINT_SIZE_RANGE:
1304 case GL_DEPTH_RANGE:
1305 {
1306 *type = GL_FLOAT;
1307 *numParams = 2;
1308 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001309 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001310 case GL_COLOR_CLEAR_VALUE:
1311 case GL_BLEND_COLOR:
1312 {
1313 *type = GL_FLOAT;
1314 *numParams = 4;
1315 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001316 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001317 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001318 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001319 {
1320 return false;
1321 }
1322 *type = GL_FLOAT;
1323 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001324 return true;
Ian Ewell53f59f42016-01-28 17:36:55 -05001325 case GL_TIMESTAMP_EXT:
1326 if (!mExtensions.disjointTimerQuery)
1327 {
1328 return false;
1329 }
1330 *type = GL_INT_64_ANGLEX;
1331 *numParams = 1;
1332 return true;
1333 case GL_GPU_DISJOINT_EXT:
1334 if (!mExtensions.disjointTimerQuery)
1335 {
1336 return false;
1337 }
1338 *type = GL_INT;
1339 *numParams = 1;
1340 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001341 }
1342
Geoff Lang70d0f492015-12-10 17:45:46 -05001343 if (mExtensions.debug)
1344 {
1345 switch (pname)
1346 {
1347 case GL_DEBUG_LOGGED_MESSAGES:
1348 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1349 case GL_DEBUG_GROUP_STACK_DEPTH:
1350 case GL_MAX_DEBUG_MESSAGE_LENGTH:
1351 case GL_MAX_DEBUG_LOGGED_MESSAGES:
1352 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
1353 case GL_MAX_LABEL_LENGTH:
1354 *type = GL_INT;
1355 *numParams = 1;
1356 return true;
1357
1358 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1359 case GL_DEBUG_OUTPUT:
1360 *type = GL_BOOL;
1361 *numParams = 1;
1362 return true;
1363 }
1364 }
1365
Austin Kinrossbc781f32015-10-26 09:27:38 -07001366 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
1367 switch (pname)
1368 {
1369 case GL_PACK_ROW_LENGTH:
1370 case GL_PACK_SKIP_ROWS:
1371 case GL_PACK_SKIP_PIXELS:
1372 if ((mClientVersion < 3) && !mExtensions.packSubimage)
1373 {
1374 return false;
1375 }
1376 *type = GL_INT;
1377 *numParams = 1;
1378 return true;
1379 case GL_UNPACK_ROW_LENGTH:
1380 case GL_UNPACK_SKIP_ROWS:
1381 case GL_UNPACK_SKIP_PIXELS:
1382 if ((mClientVersion < 3) && !mExtensions.unpackSubimage)
1383 {
1384 return false;
1385 }
1386 *type = GL_INT;
1387 *numParams = 1;
1388 return true;
1389 case GL_VERTEX_ARRAY_BINDING:
1390 if ((mClientVersion < 3) && !mExtensions.vertexArrayObject)
1391 {
1392 return false;
1393 }
1394 *type = GL_INT;
1395 *numParams = 1;
1396 return true;
Yuly Novikov5807a532015-12-03 13:01:22 -05001397 case GL_PIXEL_PACK_BUFFER_BINDING:
1398 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1399 if ((mClientVersion < 3) && !mExtensions.pixelBufferObject)
1400 {
1401 return false;
1402 }
1403 *type = GL_INT;
1404 *numParams = 1;
1405 return true;
Austin Kinrossbc781f32015-10-26 09:27:38 -07001406 }
1407
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001408 if (mClientVersion < 3)
1409 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001410 return false;
1411 }
1412
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001413 // Check for ES3.0+ parameter names
1414 switch (pname)
1415 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001416 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1417 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001418 case GL_UNIFORM_BUFFER_BINDING:
1419 case GL_TRANSFORM_FEEDBACK_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001420 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001421 case GL_COPY_READ_BUFFER_BINDING:
1422 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001423 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001424 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001425 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001426 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001427 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1428 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1429 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001430 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1431 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001432 case GL_MAX_VARYING_COMPONENTS:
Jamie Madill38850df2013-07-19 16:36:55 -04001433 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1434 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lange6d4e122015-06-29 13:33:55 -04001435 case GL_MIN_PROGRAM_TEXEL_OFFSET:
1436 case GL_MAX_PROGRAM_TEXEL_OFFSET:
Geoff Lang23c81692013-08-12 10:46:58 -04001437 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001438 case GL_MAJOR_VERSION:
1439 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001440 case GL_MAX_ELEMENTS_INDICES:
1441 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001442 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001443 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001444 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
Minmin Gongadff67b2015-10-14 10:34:45 -04001445 case GL_UNPACK_IMAGE_HEIGHT:
Jamie Madill023a2902015-10-23 16:43:24 +00001446 case GL_UNPACK_SKIP_IMAGES:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001447 {
1448 *type = GL_INT;
1449 *numParams = 1;
1450 }
1451 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001452
1453 case GL_MAX_ELEMENT_INDEX:
1454 case GL_MAX_UNIFORM_BLOCK_SIZE:
1455 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1456 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1457 case GL_MAX_SERVER_WAIT_TIMEOUT:
1458 {
1459 *type = GL_INT_64_ANGLEX;
1460 *numParams = 1;
1461 }
1462 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001463
1464 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001465 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madille2cd53d2015-10-27 11:15:46 -04001466 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
Geoff Langab831f02015-12-01 09:39:10 -05001467 case GL_RASTERIZER_DISCARD:
Jamie Madill2e503552013-12-19 13:48:34 -05001468 {
1469 *type = GL_BOOL;
1470 *numParams = 1;
1471 }
1472 return true;
Geoff Lange6d4e122015-06-29 13:33:55 -04001473
1474 case GL_MAX_TEXTURE_LOD_BIAS:
1475 {
1476 *type = GL_FLOAT;
1477 *numParams = 1;
1478 }
1479 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001480 }
1481
1482 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001483}
1484
Shannon Woods1b2fb852013-08-19 14:28:48 -04001485bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1486{
1487 if (mClientVersion < 3)
1488 {
1489 return false;
1490 }
1491
1492 switch (target)
1493 {
1494 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1495 case GL_UNIFORM_BUFFER_BINDING:
1496 {
1497 *type = GL_INT;
1498 *numParams = 1;
1499 }
1500 return true;
1501 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1502 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1503 case GL_UNIFORM_BUFFER_START:
1504 case GL_UNIFORM_BUFFER_SIZE:
1505 {
1506 *type = GL_INT_64_ANGLEX;
1507 *numParams = 1;
1508 }
1509 }
1510
1511 return false;
1512}
1513
Geoff Langf6db0982015-08-25 13:04:00 -04001514Error Context::drawArrays(GLenum mode, GLint first, GLsizei count)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001515{
Jamie Madill1b94d432015-08-07 13:23:23 -04001516 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001517 Error error = mRenderer->drawArrays(getData(), mode, first, count);
Geoff Lang520c4ae2015-05-05 13:12:36 -04001518 if (error.isError())
1519 {
1520 return error;
1521 }
1522
Geoff Langf6db0982015-08-25 13:04:00 -04001523 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
Geoff Lang520c4ae2015-05-05 13:12:36 -04001524
1525 return Error(GL_NO_ERROR);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001526}
1527
Geoff Langf6db0982015-08-25 13:04:00 -04001528Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1529{
1530 syncRendererState();
1531 Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount);
1532 if (error.isError())
1533 {
1534 return error;
1535 }
1536
1537 MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback());
1538
1539 return Error(GL_NO_ERROR);
1540}
1541
1542Error Context::drawElements(GLenum mode,
1543 GLsizei count,
1544 GLenum type,
1545 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001546 const IndexRange &indexRange)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001547{
Jamie Madill1b94d432015-08-07 13:23:23 -04001548 syncRendererState();
Geoff Langf6db0982015-08-25 13:04:00 -04001549 return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange);
1550}
1551
1552Error Context::drawElementsInstanced(GLenum mode,
1553 GLsizei count,
1554 GLenum type,
1555 const GLvoid *indices,
1556 GLsizei instances,
Geoff Lang3edfe032015-09-04 16:38:24 -04001557 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001558{
1559 syncRendererState();
1560 return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances,
1561 indexRange);
1562}
1563
1564Error Context::drawRangeElements(GLenum mode,
1565 GLuint start,
1566 GLuint end,
1567 GLsizei count,
1568 GLenum type,
1569 const GLvoid *indices,
Geoff Lang3edfe032015-09-04 16:38:24 -04001570 const IndexRange &indexRange)
Geoff Langf6db0982015-08-25 13:04:00 -04001571{
1572 syncRendererState();
1573 return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices,
1574 indexRange);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001575}
1576
Geoff Lang129753a2015-01-09 16:52:09 -05001577Error Context::flush()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001578{
Geoff Lang129753a2015-01-09 16:52:09 -05001579 return mRenderer->flush();
1580}
1581
1582Error Context::finish()
1583{
1584 return mRenderer->finish();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001585}
1586
Austin Kinross6ee1e782015-05-29 17:05:37 -07001587void Context::insertEventMarker(GLsizei length, const char *marker)
1588{
1589 ASSERT(mRenderer);
1590 mRenderer->insertEventMarker(length, marker);
1591}
1592
1593void Context::pushGroupMarker(GLsizei length, const char *marker)
1594{
1595 ASSERT(mRenderer);
1596 mRenderer->pushGroupMarker(length, marker);
1597}
1598
1599void Context::popGroupMarker()
1600{
1601 ASSERT(mRenderer);
1602 mRenderer->popGroupMarker();
1603}
1604
Geoff Langda5777c2014-07-11 09:52:58 -04001605void Context::recordError(const Error &error)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001606{
Geoff Langda5777c2014-07-11 09:52:58 -04001607 if (error.isError())
1608 {
1609 mErrors.insert(error.getCode());
Geoff Lang70d0f492015-12-10 17:45:46 -05001610
1611 if (!error.getMessage().empty())
1612 {
1613 auto &debug = mState.getDebug();
1614 debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
1615 GL_DEBUG_SEVERITY_HIGH, error.getMessage());
1616 }
Geoff Langda5777c2014-07-11 09:52:58 -04001617 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001618}
1619
1620// Get one of the recorded errors and clear its flag, if any.
1621// [OpenGL ES 2.0.24] section 2.5 page 13.
1622GLenum Context::getError()
1623{
Geoff Langda5777c2014-07-11 09:52:58 -04001624 if (mErrors.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001625 {
Geoff Langda5777c2014-07-11 09:52:58 -04001626 return GL_NO_ERROR;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001627 }
Geoff Langda5777c2014-07-11 09:52:58 -04001628 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001629 {
Geoff Langda5777c2014-07-11 09:52:58 -04001630 GLenum error = *mErrors.begin();
1631 mErrors.erase(mErrors.begin());
1632 return error;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001633 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001634}
1635
1636GLenum Context::getResetStatus()
1637{
Jamie Madill93e13fb2014-11-06 15:27:25 -05001638 //TODO(jmadill): needs MANGLE reworking
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001639 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001640 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001641 // mResetStatus will be set by the markContextLost callback
1642 // in the case a notification is sent
Jamie Madill4c76fea2014-11-24 11:38:52 -05001643 if (mRenderer->testDeviceLost())
Jamie Madill9dd0cf02014-11-24 11:38:51 -05001644 {
1645 mRenderer->notifyDeviceLost();
1646 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001647 }
1648
1649 GLenum status = mResetStatus;
1650
1651 if (mResetStatus != GL_NO_ERROR)
1652 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001653 ASSERT(mContextLost);
1654
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001655 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656 {
1657 mResetStatus = GL_NO_ERROR;
1658 }
1659 }
Jamie Madill893ab082014-05-16 16:56:10 -04001660
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001661 return status;
1662}
1663
1664bool Context::isResetNotificationEnabled()
1665{
1666 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1667}
1668
Corentin Walleze3b10e82015-05-20 11:06:25 -04001669const egl::Config *Context::getConfig() const
Régis Fénéon83107972015-02-05 12:57:44 +01001670{
Corentin Walleze3b10e82015-05-20 11:06:25 -04001671 return mConfig;
Régis Fénéon83107972015-02-05 12:57:44 +01001672}
1673
1674EGLenum Context::getClientType() const
1675{
1676 return mClientType;
1677}
1678
1679EGLenum Context::getRenderBuffer() const
1680{
Corentin Wallez37c39792015-08-20 14:19:46 -04001681 auto framebufferIt = mFramebufferMap.find(0);
1682 if (framebufferIt != mFramebufferMap.end())
1683 {
1684 const Framebuffer *framebuffer = framebufferIt->second;
1685 const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
1686
1687 ASSERT(backAttachment != nullptr);
1688 return backAttachment->getSurface()->getRenderBuffer();
1689 }
1690 else
1691 {
1692 return EGL_NONE;
1693 }
Régis Fénéon83107972015-02-05 12:57:44 +01001694}
1695
Geoff Lang36167ab2015-12-07 10:27:14 -05001696void Context::checkVertexArrayAllocation(GLuint vertexArray)
1697{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001698 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001699 if (!getVertexArray(vertexArray))
1700 {
1701 VertexArray *vertexArrayObject =
1702 new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
1703 mVertexArrayMap[vertexArray] = vertexArrayObject;
1704 }
1705}
1706
1707void Context::checkTransformFeedbackAllocation(GLuint transformFeedback)
1708{
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001709 // Only called after a prior call to Gen.
Geoff Lang36167ab2015-12-07 10:27:14 -05001710 if (!getTransformFeedback(transformFeedback))
1711 {
1712 TransformFeedback *transformFeedbackObject =
1713 new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps);
1714 transformFeedbackObject->addRef();
1715 mTransformFeedbackMap[transformFeedback] = transformFeedbackObject;
1716 }
1717}
1718
Jamie Madill5bf9ff42016-02-01 11:13:03 -05001719Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer)
1720{
1721 // Can be called from Bind without a prior call to Gen.
1722 auto framebufferIt = mFramebufferMap.find(framebuffer);
1723 bool neverCreated = framebufferIt == mFramebufferMap.end();
1724 if (neverCreated || framebufferIt->second == nullptr)
1725 {
1726 Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer);
1727 if (neverCreated)
1728 {
1729 mFramebufferHandleAllocator.reserve(framebuffer);
1730 mFramebufferMap[framebuffer] = newFBO;
1731 return newFBO;
1732 }
1733
1734 framebufferIt->second = newFBO;
1735 }
1736
1737 return framebufferIt->second;
1738}
1739
Geoff Lang36167ab2015-12-07 10:27:14 -05001740bool Context::isVertexArrayGenerated(GLuint vertexArray)
1741{
1742 return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end();
1743}
1744
1745bool Context::isTransformFeedbackGenerated(GLuint transformFeedback)
1746{
1747 return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end();
1748}
1749
Shannon Woods53a94a82014-06-24 15:20:36 -04001750void Context::detachTexture(GLuint texture)
1751{
1752 // Simple pass-through to State's detachTexture method, as textures do not require
1753 // allocation map management either here or in the resource manager at detach time.
1754 // Zero textures are held by the Context, and we don't attempt to request them from
1755 // the State.
Jamie Madille6382c32014-11-07 15:05:26 -05001756 mState.detachTexture(mZeroTextures, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -04001757}
1758
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001759void Context::detachBuffer(GLuint buffer)
1760{
Yuly Novikov5807a532015-12-03 13:01:22 -05001761 // Simple pass-through to State's detachBuffer method, since
1762 // only buffer attachments to container objects that are bound to the current context
1763 // should be detached. And all those are available in State.
Shannon Woods53a94a82014-06-24 15:20:36 -04001764
Yuly Novikov5807a532015-12-03 13:01:22 -05001765 // [OpenGL ES 3.2] section 5.1.2 page 45:
1766 // Attachments to unbound container objects, such as
1767 // deletion of a buffer attached to a vertex array object which is not bound to the context,
1768 // are not affected and continue to act as references on the deleted object
1769 mState.detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001770}
1771
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001772void Context::detachFramebuffer(GLuint framebuffer)
1773{
Shannon Woods53a94a82014-06-24 15:20:36 -04001774 // Framebuffer detachment is handled by Context, because 0 is a valid
1775 // Framebuffer object, and a pointer to it must be passed from Context
1776 // to State at binding time.
1777
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001778 // [OpenGL ES 2.0.24] section 4.4 page 107:
1779 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1780 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1781
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001782 if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001783 {
1784 bindReadFramebuffer(0);
1785 }
1786
Gregoire Payen de La Garanderieed54e5d2015-03-17 16:51:24 +00001787 if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001788 {
1789 bindDrawFramebuffer(0);
1790 }
1791}
1792
1793void Context::detachRenderbuffer(GLuint renderbuffer)
1794{
Shannon Woods53a94a82014-06-24 15:20:36 -04001795 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001796}
1797
Jamie Madill57a89722013-07-02 11:57:03 -04001798void Context::detachVertexArray(GLuint vertexArray)
1799{
Jamie Madill77a72f62015-04-14 11:18:32 -04001800 // Vertex array detachment is handled by Context, because 0 is a valid
1801 // VAO, and a pointer to it must be passed from Context to State at
Shannon Woods53a94a82014-06-24 15:20:36 -04001802 // binding time.
1803
Jamie Madill57a89722013-07-02 11:57:03 -04001804 // [OpenGL ES 3.0.2] section 2.10 page 43:
1805 // If a vertex array object that is currently bound is deleted, the binding
1806 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04001807 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04001808 {
1809 bindVertexArray(0);
1810 }
1811}
1812
Geoff Langc8058452014-02-03 12:04:11 -05001813void Context::detachTransformFeedback(GLuint transformFeedback)
1814{
Shannon Woods53a94a82014-06-24 15:20:36 -04001815 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05001816}
1817
Jamie Madilldc356042013-07-19 16:36:57 -04001818void Context::detachSampler(GLuint sampler)
1819{
Shannon Woods53a94a82014-06-24 15:20:36 -04001820 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04001821}
1822
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001823void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
1824{
Jamie Madill0b9e9032015-08-17 11:51:52 +00001825 mState.setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001826}
1827
Jamie Madille29d1672013-07-19 16:36:57 -04001828void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1829{
1830 mResourceManager->checkSamplerAllocation(sampler);
1831
1832 Sampler *samplerObject = getSampler(sampler);
1833 ASSERT(samplerObject);
1834
Geoff Lang69cce582015-09-17 13:20:36 -04001835 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001836 switch (pname)
1837 {
Geoff Lang69cce582015-09-17 13:20:36 -04001838 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1839 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1840 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1841 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1842 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1843 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast<GLfloat>(param), getExtensions().maxTextureAnisotropy)); break;
1844 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1845 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1846 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1847 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1848 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001849 }
Geoff Lang69cce582015-09-17 13:20:36 -04001850 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001851}
1852
1853void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1854{
1855 mResourceManager->checkSamplerAllocation(sampler);
1856
1857 Sampler *samplerObject = getSampler(sampler);
1858 ASSERT(samplerObject);
1859
Geoff Lang69cce582015-09-17 13:20:36 -04001860 // clang-format off
Jamie Madille29d1672013-07-19 16:36:57 -04001861 switch (pname)
1862 {
Geoff Lang69cce582015-09-17 13:20:36 -04001863 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
1864 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
1865 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
1866 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
1867 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
1868 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break;
1869 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1870 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1871 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround<GLenum>(param)); break;
1872 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround<GLenum>(param)); break;
1873 default: UNREACHABLE(); break;
Jamie Madille29d1672013-07-19 16:36:57 -04001874 }
Geoff Lang69cce582015-09-17 13:20:36 -04001875 // clang-format on
Jamie Madille29d1672013-07-19 16:36:57 -04001876}
1877
Jamie Madill9675b802013-07-19 16:36:59 -04001878GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1879{
1880 mResourceManager->checkSamplerAllocation(sampler);
1881
1882 Sampler *samplerObject = getSampler(sampler);
1883 ASSERT(samplerObject);
1884
Geoff Lang69cce582015-09-17 13:20:36 -04001885 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001886 switch (pname)
1887 {
Geoff Lang69cce582015-09-17 13:20:36 -04001888 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1889 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1890 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1891 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1892 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1893 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1894 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
1895 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
1896 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1897 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1898 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001899 }
Geoff Lang69cce582015-09-17 13:20:36 -04001900 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001901}
1902
1903GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1904{
1905 mResourceManager->checkSamplerAllocation(sampler);
1906
1907 Sampler *samplerObject = getSampler(sampler);
1908 ASSERT(samplerObject);
1909
Geoff Lang69cce582015-09-17 13:20:36 -04001910 // clang-format off
Jamie Madill9675b802013-07-19 16:36:59 -04001911 switch (pname)
1912 {
Geoff Lang69cce582015-09-17 13:20:36 -04001913 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1914 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1915 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1916 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1917 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1918 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1919 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1920 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1921 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1922 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1923 default: UNREACHABLE(); return 0;
Jamie Madill9675b802013-07-19 16:36:59 -04001924 }
Geoff Lang69cce582015-09-17 13:20:36 -04001925 // clang-format on
Jamie Madill9675b802013-07-19 16:36:59 -04001926}
1927
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001928void Context::initRendererString()
1929{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001930 std::ostringstream rendererString;
1931 rendererString << "ANGLE (";
1932 rendererString << mRenderer->getRendererDescription();
1933 rendererString << ")";
1934
Geoff Langcec35902014-04-16 10:52:36 -04001935 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001936}
1937
Geoff Langc0b9ef42014-07-02 10:02:37 -04001938const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001939{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00001940 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001941}
1942
Geoff Langcec35902014-04-16 10:52:36 -04001943void Context::initExtensionStrings()
1944{
Geoff Lang493daf52014-07-03 13:38:44 -04001945 mExtensionStrings = mExtensions.getStrings();
Geoff Langcec35902014-04-16 10:52:36 -04001946
Geoff Langc0b9ef42014-07-02 10:02:37 -04001947 std::ostringstream combinedStringStream;
1948 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
1949 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04001950}
1951
Geoff Langc0b9ef42014-07-02 10:02:37 -04001952const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04001953{
1954 return mExtensionString;
1955}
1956
Geoff Langc0b9ef42014-07-02 10:02:37 -04001957const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04001958{
1959 return mExtensionStrings[idx];
1960}
1961
1962size_t Context::getExtensionStringCount() const
1963{
1964 return mExtensionStrings.size();
1965}
1966
Geoff Lang493daf52014-07-03 13:38:44 -04001967void Context::initCaps(GLuint clientVersion)
1968{
1969 mCaps = mRenderer->getRendererCaps();
1970
1971 mExtensions = mRenderer->getRendererExtensions();
1972
Austin Kinross02df7962015-07-01 10:03:42 -07001973 mLimitations = mRenderer->getRendererLimitations();
1974
Geoff Lang493daf52014-07-03 13:38:44 -04001975 if (clientVersion < 3)
1976 {
1977 // Disable ES3+ extensions
1978 mExtensions.colorBufferFloat = false;
1979 }
1980
1981 if (clientVersion > 2)
1982 {
1983 // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
1984 //mExtensions.sRGB = false;
1985 }
1986
Geoff Lang70d0f492015-12-10 17:45:46 -05001987 // Explicitly enable GL_KHR_debug
1988 mExtensions.debug = true;
1989 mExtensions.maxDebugMessageLength = 1024;
1990 mExtensions.maxDebugLoggedMessages = 1024;
1991 mExtensions.maxDebugGroupStackDepth = 1024;
1992 mExtensions.maxLabelLength = 1024;
1993
Geoff Lang301d1612014-07-09 10:34:37 -04001994 // Apply implementation limits
1995 mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
Geoff Lang301d1612014-07-09 10:34:37 -04001996 mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
1997 mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
1998
1999 mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
Geoff Lang3a61c322014-07-10 13:01:54 -04002000
Geoff Lang900013c2014-07-07 11:32:19 -04002001 mCaps.compressedTextureFormats.clear();
2002
Geoff Lang493daf52014-07-03 13:38:44 -04002003 const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2004 for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2005 {
2006 GLenum format = i->first;
2007 TextureCaps formatCaps = i->second;
2008
Geoff Lang5d601382014-07-22 15:14:06 -04002009 const InternalFormat &formatInfo = GetInternalFormatInfo(format);
Geoff Langd87878e2014-09-19 15:42:59 -04002010
Geoff Lang0d8b7242015-09-09 14:56:53 -04002011 // Update the format caps based on the client version and extensions.
2012 // Caps are AND'd with the renderer caps because some core formats are still unsupported in
2013 // ES3.
2014 formatCaps.texturable =
2015 formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions);
2016 formatCaps.renderable =
2017 formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions);
2018 formatCaps.filterable =
2019 formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions);
Geoff Langd87878e2014-09-19 15:42:59 -04002020
2021 // OpenGL ES does not support multisampling with integer formats
2022 if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
Geoff Lang493daf52014-07-03 13:38:44 -04002023 {
Geoff Langd87878e2014-09-19 15:42:59 -04002024 formatCaps.sampleCounts.clear();
Geoff Lang493daf52014-07-03 13:38:44 -04002025 }
Geoff Langd87878e2014-09-19 15:42:59 -04002026
2027 if (formatCaps.texturable && formatInfo.compressed)
2028 {
2029 mCaps.compressedTextureFormats.push_back(format);
2030 }
2031
2032 mTextureCaps.insert(format, formatCaps);
Geoff Lang493daf52014-07-03 13:38:44 -04002033 }
2034}
2035
Jamie Madill1b94d432015-08-07 13:23:23 -04002036void Context::syncRendererState()
2037{
2038 const State::DirtyBits &dirtyBits = mState.getDirtyBits();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002039 mRenderer->syncState(mState, dirtyBits);
2040 mState.clearDirtyBits();
2041 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002042}
2043
2044void Context::syncRendererState(const State::DirtyBits &bitMask)
2045{
2046 const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002047 mRenderer->syncState(mState, dirtyBits);
2048 mState.clearDirtyBits(dirtyBits);
2049
2050 // TODO(jmadill): Filter objects by bitMask somehow?
2051 mState.syncDirtyObjects();
Jamie Madill1b94d432015-08-07 13:23:23 -04002052}
Jamie Madillc29968b2016-01-20 11:17:23 -05002053
2054void Context::blitFramebuffer(GLint srcX0,
2055 GLint srcY0,
2056 GLint srcX1,
2057 GLint srcY1,
2058 GLint dstX0,
2059 GLint dstY0,
2060 GLint dstX1,
2061 GLint dstY1,
2062 GLbitfield mask,
2063 GLenum filter)
2064{
2065 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2066 ASSERT(readFramebuffer);
2067
2068 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2069 ASSERT(drawFramebuffer);
2070
2071 Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2072 Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2073
2074 syncRendererState(mState.blitStateBitMask());
2075
2076 Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
2077 if (error.isError())
2078 {
2079 recordError(error);
2080 return;
2081 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002082}
Jamie Madillc29968b2016-01-20 11:17:23 -05002083
2084void Context::clear(GLbitfield mask)
2085{
2086 // Sync the clear state
2087 syncRendererState(mState.clearStateBitMask());
2088
2089 Error error = mState.getDrawFramebuffer()->clear(mData, mask);
2090 if (error.isError())
2091 {
2092 recordError(error);
2093 }
2094}
2095
2096void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
2097{
2098 // Sync the clear state
2099 syncRendererState(mState.clearStateBitMask());
2100
2101 Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
2102 if (error.isError())
2103 {
2104 recordError(error);
2105 }
2106}
2107
2108void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
2109{
2110 // Sync the clear state
2111 syncRendererState(mState.clearStateBitMask());
2112
2113 Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
2114 if (error.isError())
2115 {
2116 recordError(error);
2117 }
2118}
2119
2120void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
2121{
2122 // Sync the clear state
2123 syncRendererState(mState.clearStateBitMask());
2124
2125 Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
2126 if (error.isError())
2127 {
2128 recordError(error);
2129 }
2130}
2131
2132void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
2133{
2134 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
2135 ASSERT(framebufferObject);
2136
2137 // If a buffer is not present, the clear has no effect
2138 if (framebufferObject->getDepthbuffer() == nullptr &&
2139 framebufferObject->getStencilbuffer() == nullptr)
2140 {
2141 return;
2142 }
2143
2144 // Sync the clear state
2145 syncRendererState(mState.clearStateBitMask());
2146
2147 Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
2148 if (error.isError())
2149 {
2150 recordError(error);
2151 }
2152}
2153
2154void Context::readPixels(GLint x,
2155 GLint y,
2156 GLsizei width,
2157 GLsizei height,
2158 GLenum format,
2159 GLenum type,
2160 GLvoid *pixels)
2161{
2162 // Sync pack state
2163 syncRendererState(mState.packStateBitMask());
2164
2165 Framebuffer *framebufferObject = mState.getReadFramebuffer();
2166 ASSERT(framebufferObject);
2167
2168 Rectangle area(x, y, width, height);
2169 Error error = framebufferObject->readPixels(mState, area, format, type, pixels);
2170 if (error.isError())
2171 {
2172 recordError(error);
2173 }
2174}
2175
2176void Context::copyTexImage2D(GLenum target,
2177 GLint level,
2178 GLenum internalformat,
2179 GLint x,
2180 GLint y,
2181 GLsizei width,
2182 GLsizei height,
2183 GLint border)
2184{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002185 // Only sync the read FBO
2186 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2187
Jamie Madillc29968b2016-01-20 11:17:23 -05002188 Rectangle sourceArea(x, y, width, height);
2189
2190 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2191 Texture *texture =
2192 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2193 Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
2194 if (error.isError())
2195 {
2196 recordError(error);
2197 }
2198}
2199
2200void Context::copyTexSubImage2D(GLenum target,
2201 GLint level,
2202 GLint xoffset,
2203 GLint yoffset,
2204 GLint x,
2205 GLint y,
2206 GLsizei width,
2207 GLsizei height)
2208{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002209 // Only sync the read FBO
2210 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2211
Jamie Madillc29968b2016-01-20 11:17:23 -05002212 Offset destOffset(xoffset, yoffset, 0);
2213 Rectangle sourceArea(x, y, width, height);
2214
2215 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2216 Texture *texture =
2217 getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
2218 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2219 if (error.isError())
2220 {
2221 recordError(error);
2222 }
2223}
2224
2225void Context::copyTexSubImage3D(GLenum target,
2226 GLint level,
2227 GLint xoffset,
2228 GLint yoffset,
2229 GLint zoffset,
2230 GLint x,
2231 GLint y,
2232 GLsizei width,
2233 GLsizei height)
2234{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002235 // Only sync the read FBO
2236 mState.syncDirtyObject(GL_READ_FRAMEBUFFER);
2237
Jamie Madillc29968b2016-01-20 11:17:23 -05002238 Offset destOffset(xoffset, yoffset, zoffset);
2239 Rectangle sourceArea(x, y, width, height);
2240
2241 const Framebuffer *framebuffer = mState.getReadFramebuffer();
2242 Texture *texture = getTargetTexture(target);
2243 Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
2244 if (error.isError())
2245 {
2246 recordError(error);
2247 }
2248}
2249
2250void Context::framebufferTexture2D(GLenum target,
2251 GLenum attachment,
2252 GLenum textarget,
2253 GLuint texture,
2254 GLint level)
2255{
2256 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2257 ASSERT(framebuffer);
2258
2259 if (texture != 0)
2260 {
2261 Texture *textureObj = getTexture(texture);
2262
2263 ImageIndex index = ImageIndex::MakeInvalid();
2264
2265 if (textarget == GL_TEXTURE_2D)
2266 {
2267 index = ImageIndex::Make2D(level);
2268 }
2269 else
2270 {
2271 ASSERT(IsCubeMapTextureTarget(textarget));
2272 index = ImageIndex::MakeCube(textarget, level);
2273 }
2274
2275 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
2276 }
2277 else
2278 {
2279 framebuffer->resetAttachment(attachment);
2280 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002281
2282 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002283}
2284
2285void Context::framebufferRenderbuffer(GLenum target,
2286 GLenum attachment,
2287 GLenum renderbuffertarget,
2288 GLuint renderbuffer)
2289{
2290 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2291 ASSERT(framebuffer);
2292
2293 if (renderbuffer != 0)
2294 {
2295 Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
2296 framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(),
2297 renderbufferObject);
2298 }
2299 else
2300 {
2301 framebuffer->resetAttachment(attachment);
2302 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002303
2304 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002305}
2306
2307void Context::framebufferTextureLayer(GLenum target,
2308 GLenum attachment,
2309 GLuint texture,
2310 GLint level,
2311 GLint layer)
2312{
2313 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2314 ASSERT(framebuffer);
2315
2316 if (texture != 0)
2317 {
2318 Texture *textureObject = getTexture(texture);
2319
2320 ImageIndex index = ImageIndex::MakeInvalid();
2321
2322 if (textureObject->getTarget() == GL_TEXTURE_3D)
2323 {
2324 index = ImageIndex::Make3D(level, layer);
2325 }
2326 else
2327 {
2328 ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
2329 index = ImageIndex::Make2DArray(level, layer);
2330 }
2331
2332 framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
2333 }
2334 else
2335 {
2336 framebuffer->resetAttachment(attachment);
2337 }
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002338
2339 mState.setObjectDirty(target);
Jamie Madillc29968b2016-01-20 11:17:23 -05002340}
2341
2342void Context::drawBuffers(GLsizei n, const GLenum *bufs)
2343{
2344 Framebuffer *framebuffer = mState.getDrawFramebuffer();
2345 ASSERT(framebuffer);
2346 framebuffer->setDrawBuffers(n, bufs);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002347 mState.setObjectDirty(GL_DRAW_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002348}
2349
2350void Context::readBuffer(GLenum mode)
2351{
2352 Framebuffer *readFBO = mState.getReadFramebuffer();
2353 readFBO->setReadBuffer(mode);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002354 mState.setObjectDirty(GL_READ_FRAMEBUFFER);
Jamie Madillc29968b2016-01-20 11:17:23 -05002355}
2356
2357void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
2358{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002359 // Only sync the FBO
2360 mState.syncDirtyObject(target);
2361
Jamie Madillc29968b2016-01-20 11:17:23 -05002362 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2363 ASSERT(framebuffer);
2364
2365 // The specification isn't clear what should be done when the framebuffer isn't complete.
2366 // We leave it up to the framebuffer implementation to decide what to do.
2367 Error error = framebuffer->discard(numAttachments, attachments);
2368 if (error.isError())
2369 {
2370 recordError(error);
2371 }
2372}
2373
2374void Context::invalidateFramebuffer(GLenum target,
2375 GLsizei numAttachments,
2376 const GLenum *attachments)
2377{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002378 // Only sync the FBO
2379 mState.syncDirtyObject(target);
2380
Jamie Madillc29968b2016-01-20 11:17:23 -05002381 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2382 ASSERT(framebuffer);
2383
2384 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2385 {
2386 Error error = framebuffer->invalidate(numAttachments, attachments);
2387 if (error.isError())
2388 {
2389 recordError(error);
2390 return;
2391 }
2392 }
2393}
2394
2395void Context::invalidateSubFramebuffer(GLenum target,
2396 GLsizei numAttachments,
2397 const GLenum *attachments,
2398 GLint x,
2399 GLint y,
2400 GLsizei width,
2401 GLsizei height)
2402{
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002403 // Only sync the FBO
2404 mState.syncDirtyObject(target);
2405
Jamie Madillc29968b2016-01-20 11:17:23 -05002406 Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
2407 ASSERT(framebuffer);
2408
2409 if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE)
2410 {
2411 Rectangle area(x, y, width, height);
2412 Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
2413 if (error.isError())
2414 {
2415 recordError(error);
2416 return;
2417 }
2418 }
2419}
2420
2421} // namespace gl