blob: 8b1d6607b4fe475470ed4862d8ed5e6ebfaa5a5d [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002//
Geoff Langeeba6e12014-02-03 13:12:30 -05003// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Context.cpp: Implements the gl::Context class, managing all GL state and performing
9// rendering operations. It is the GLES2 specific implementation of EGLContext.
10
11#include "libGLESv2/Context.h"
12
apatrick@chromium.org144f2802012-07-12 01:42:34 +000013#include "libGLESv2/main.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000014#include "common/utilities.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000015#include "libGLESv2/formatutils.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000016#include "libGLESv2/Buffer.h"
17#include "libGLESv2/Fence.h"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000018#include "libGLESv2/Framebuffer.h"
Jamie Madille261b442014-06-25 12:42:21 -040019#include "libGLESv2/FramebufferAttachment.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000020#include "libGLESv2/Renderbuffer.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000021#include "libGLESv2/Program.h"
22#include "libGLESv2/ProgramBinary.h"
23#include "libGLESv2/Query.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000024#include "libGLESv2/Texture.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000025#include "libGLESv2/ResourceManager.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070026#include "libGLESv2/renderer/d3d/IndexDataManager.h"
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000027#include "libGLESv2/renderer/RenderTarget.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000028#include "libGLESv2/renderer/Renderer.h"
Jamie Madill57a89722013-07-02 11:57:03 -040029#include "libGLESv2/VertexArray.h"
Jamie Madilldc356042013-07-19 16:36:57 -040030#include "libGLESv2/Sampler.h"
Jamie Madill1fc7e2c2014-01-21 16:47:10 -050031#include "libGLESv2/validationES.h"
Geoff Langc8058452014-02-03 12:04:11 -050032#include "libGLESv2/TransformFeedback.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000033
34#include "libEGL/Surface.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000035
36#undef near
37#undef far
38
39namespace gl
40{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +000041
Shannon Woods53a94a82014-06-24 15:20:36 -040042Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
43 : mRenderer(renderer)
apatrick@chromium.org144f2802012-07-12 01:42:34 +000044{
45 ASSERT(robustAccess == false); // Unimplemented
46
Geoff Langc0b9ef42014-07-02 10:02:37 -040047 mCaps = mRenderer->getRendererCaps();
48 mTextureCaps = mRenderer->getRendererTextureCaps();
49 mExtensions = mRenderer->getRendererExtensions();
50
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +000051 mClientVersion = clientVersion;
52
Shannon Woods53a94a82014-06-24 15:20:36 -040053 mFenceNVHandleAllocator.setBaseHandle(0);
Geoff Lang7dca1862013-07-30 16:30:46 -040054
apatrick@chromium.org144f2802012-07-12 01:42:34 +000055 if (shareContext != NULL)
56 {
57 mResourceManager = shareContext->mResourceManager;
58 mResourceManager->addRef();
59 }
60 else
61 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +000062 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +000063 }
64
65 // [OpenGL ES 2.0.24] section 3.7 page 83:
66 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
67 // and cube map texture state vectors respectively associated with them.
68 // In order that access to these initial textures not be lost, they are treated as texture
69 // objects all of whose names are 0.
70
Brandon Jonesf47bebc2014-07-09 14:28:42 -070071 mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0));
daniel@transgaming.com370482e2012-11-28 19:32:13 +000072 mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +000073 mTexture3DZero.set(new Texture3D(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +000074 mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
apatrick@chromium.org144f2802012-07-12 01:42:34 +000075
Jamie Madill57a89722013-07-02 11:57:03 -040076 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +000077 bindArrayBuffer(0);
78 bindElementArrayBuffer(0);
79 bindTextureCubeMap(0);
80 bindTexture2D(0);
81 bindReadFramebuffer(0);
82 bindDrawFramebuffer(0);
83 bindRenderbuffer(0);
84
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +000085 bindGenericUniformBuffer(0);
86 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
87 {
88 bindIndexedUniformBuffer(0, i, 0, -1);
89 }
90
91 bindGenericTransformFeedbackBuffer(0);
92 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
93 {
94 bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
95 }
96
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +000097 bindCopyReadBuffer(0);
98 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +000099 bindPixelPackBuffer(0);
100 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000101
Geoff Langc8058452014-02-03 12:04:11 -0500102 // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
103 // In the initial state, a default transform feedback object is bound and treated as
104 // a transform feedback object with a name of zero. That object is bound any time
105 // BindTransformFeedback is called with id of zero
106 mTransformFeedbackZero.set(new TransformFeedback(0));
107 bindTransformFeedback(0);
108
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000109 mInvalidEnum = false;
110 mInvalidValue = false;
111 mInvalidOperation = false;
112 mOutOfMemory = false;
113 mInvalidFramebufferOperation = false;
114
115 mHasBeenCurrent = false;
116 mContextLost = false;
117 mResetStatus = GL_NO_ERROR;
118 mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
119 mRobustAccess = robustAccess;
120
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000121 mNumCompressedTextureFormats = 0;
Shannon Woods53a94a82014-06-24 15:20:36 -0400122
123 mState.setContext(this);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000124}
125
126Context::~Context()
127{
Shannon Woods53a94a82014-06-24 15:20:36 -0400128 GLuint currentProgram = mState.getCurrentProgramId();
129 if (currentProgram != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000130 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400131 Program *programObject = mResourceManager->getProgram(currentProgram);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000132 if (programObject)
133 {
134 programObject->release();
135 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400136 currentProgram = 0;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000137 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400138 mState.setCurrentProgram(0, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000139
140 while (!mFramebufferMap.empty())
141 {
142 deleteFramebuffer(mFramebufferMap.begin()->first);
143 }
144
Jamie Madill33dc8432013-07-26 11:55:05 -0400145 while (!mFenceNVMap.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000146 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400147 deleteFenceNV(mFenceNVMap.begin()->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000148 }
149
150 while (!mQueryMap.empty())
151 {
152 deleteQuery(mQueryMap.begin()->first);
153 }
154
Jamie Madill57a89722013-07-02 11:57:03 -0400155 while (!mVertexArrayMap.empty())
156 {
157 deleteVertexArray(mVertexArrayMap.begin()->first);
158 }
159
Geoff Langc8058452014-02-03 12:04:11 -0500160 mTransformFeedbackZero.set(NULL);
161 while (!mTransformFeedbackMap.empty())
162 {
163 deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
164 }
165
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000166 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
167 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000168 mIncompleteTextures[type].set(NULL);
169 }
170
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000171 mTexture2DZero.set(NULL);
172 mTextureCubeMapZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000173 mTexture3DZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000174 mTexture2DArrayZero.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000175
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000176 mResourceManager->release();
177}
178
daniel@transgaming.comad629872012-11-28 19:32:06 +0000179void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000180{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000181 if (!mHasBeenCurrent)
182 {
daniel@transgaming.com9549bea2012-11-28 20:57:23 +0000183 mMajorShaderModel = mRenderer->getMajorShaderModel();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000184 mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000185
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000186 mNumCompressedTextureFormats = 0;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400187 if (mExtensions.textureCompressionDXT1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000188 {
189 mNumCompressedTextureFormats += 2;
190 }
Geoff Langc0b9ef42014-07-02 10:02:37 -0400191 if (mExtensions.textureCompressionDXT3)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000192 {
193 mNumCompressedTextureFormats += 1;
194 }
Geoff Langc0b9ef42014-07-02 10:02:37 -0400195 if (mExtensions.textureCompressionDXT5)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000196 {
197 mNumCompressedTextureFormats += 1;
198 }
199
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000200 initRendererString();
Geoff Langcec35902014-04-16 10:52:36 -0400201 initExtensionStrings();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000202
Shannon Woods53a94a82014-06-24 15:20:36 -0400203 mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
204 mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000205
206 mHasBeenCurrent = true;
207 }
208
daniel@transgaming.com024786d2012-10-31 18:42:55 +0000209 // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +0000210 rx::SwapChain *swapchain = surface->getSwapChain();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000211
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000212 Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
213 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000214 Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000215
216 setFramebufferZero(framebufferZero);
shannon.woods%transgaming.com@gtempaccount.com785f1962013-04-13 03:34:45 +0000217
218 // Store the current client version in the renderer
219 mRenderer->setCurrentClientVersion(mClientVersion);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000220}
221
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000222// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000223void Context::markContextLost()
224{
225 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
226 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
227 mContextLost = true;
228}
229
230bool Context::isContextLost()
231{
232 return mContextLost;
233}
234
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000235GLuint Context::createBuffer()
236{
237 return mResourceManager->createBuffer();
238}
239
240GLuint Context::createProgram()
241{
242 return mResourceManager->createProgram();
243}
244
245GLuint Context::createShader(GLenum type)
246{
247 return mResourceManager->createShader(type);
248}
249
250GLuint Context::createTexture()
251{
252 return mResourceManager->createTexture();
253}
254
255GLuint Context::createRenderbuffer()
256{
257 return mResourceManager->createRenderbuffer();
258}
259
Jamie Madillcd055f82013-07-26 11:55:15 -0400260GLsync Context::createFenceSync(GLenum condition)
261{
262 GLuint handle = mResourceManager->createFenceSync();
263
264 gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
265 ASSERT(fenceSync);
266
267 fenceSync->set(condition);
268
269 return reinterpret_cast<GLsync>(handle);
270}
271
Jamie Madill57a89722013-07-02 11:57:03 -0400272GLuint Context::createVertexArray()
273{
274 GLuint handle = mVertexArrayHandleAllocator.allocate();
275
Jamie Madilld1028542013-07-02 11:57:04 -0400276 // Although the spec states VAO state is not initialized until the object is bound,
277 // we create it immediately. The resulting behaviour is transparent to the application,
278 // since it's not currently possible to access the state until the object is bound.
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400279 VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
280 mVertexArrayMap[handle] = vertexArray;
Jamie Madill57a89722013-07-02 11:57:03 -0400281 return handle;
282}
283
Jamie Madilldc356042013-07-19 16:36:57 -0400284GLuint Context::createSampler()
285{
286 return mResourceManager->createSampler();
287}
288
Geoff Langc8058452014-02-03 12:04:11 -0500289GLuint Context::createTransformFeedback()
290{
291 GLuint handle = mTransformFeedbackAllocator.allocate();
292 TransformFeedback *transformFeedback = new TransformFeedback(handle);
293 transformFeedback->addRef();
294 mTransformFeedbackMap[handle] = transformFeedback;
295 return handle;
296}
297
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000298// Returns an unused framebuffer name
299GLuint Context::createFramebuffer()
300{
301 GLuint handle = mFramebufferHandleAllocator.allocate();
302
303 mFramebufferMap[handle] = NULL;
304
305 return handle;
306}
307
Jamie Madill33dc8432013-07-26 11:55:05 -0400308GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000309{
Jamie Madill33dc8432013-07-26 11:55:05 -0400310 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000311
Jamie Madill33dc8432013-07-26 11:55:05 -0400312 mFenceNVMap[handle] = new FenceNV(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000313
314 return handle;
315}
316
317// Returns an unused query name
318GLuint Context::createQuery()
319{
320 GLuint handle = mQueryHandleAllocator.allocate();
321
322 mQueryMap[handle] = NULL;
323
324 return handle;
325}
326
327void Context::deleteBuffer(GLuint buffer)
328{
329 if (mResourceManager->getBuffer(buffer))
330 {
331 detachBuffer(buffer);
332 }
Jamie Madill893ab082014-05-16 16:56:10 -0400333
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000334 mResourceManager->deleteBuffer(buffer);
335}
336
337void Context::deleteShader(GLuint shader)
338{
339 mResourceManager->deleteShader(shader);
340}
341
342void Context::deleteProgram(GLuint program)
343{
344 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000345}
346
347void Context::deleteTexture(GLuint texture)
348{
349 if (mResourceManager->getTexture(texture))
350 {
351 detachTexture(texture);
352 }
353
354 mResourceManager->deleteTexture(texture);
355}
356
357void Context::deleteRenderbuffer(GLuint renderbuffer)
358{
359 if (mResourceManager->getRenderbuffer(renderbuffer))
360 {
361 detachRenderbuffer(renderbuffer);
362 }
Jamie Madill893ab082014-05-16 16:56:10 -0400363
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000364 mResourceManager->deleteRenderbuffer(renderbuffer);
365}
366
Jamie Madillcd055f82013-07-26 11:55:15 -0400367void Context::deleteFenceSync(GLsync fenceSync)
368{
369 // The spec specifies the underlying Fence object is not deleted until all current
370 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
371 // and since our API is currently designed for being called from a single thread, we can delete
372 // the fence immediately.
373 mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
374}
375
Jamie Madill57a89722013-07-02 11:57:03 -0400376void Context::deleteVertexArray(GLuint vertexArray)
377{
378 auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
379
380 if (vertexArrayObject != mVertexArrayMap.end())
381 {
382 detachVertexArray(vertexArray);
383
384 mVertexArrayHandleAllocator.release(vertexArrayObject->first);
385 delete vertexArrayObject->second;
386 mVertexArrayMap.erase(vertexArrayObject);
387 }
388}
389
Jamie Madilldc356042013-07-19 16:36:57 -0400390void Context::deleteSampler(GLuint sampler)
391{
392 if (mResourceManager->getSampler(sampler))
393 {
394 detachSampler(sampler);
395 }
396
397 mResourceManager->deleteSampler(sampler);
398}
399
Geoff Langc8058452014-02-03 12:04:11 -0500400void Context::deleteTransformFeedback(GLuint transformFeedback)
401{
402 TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
403 if (iter != mTransformFeedbackMap.end())
404 {
405 detachTransformFeedback(transformFeedback);
406 mTransformFeedbackAllocator.release(transformFeedback);
407 iter->second->release();
408 mTransformFeedbackMap.erase(iter);
409 }
410}
411
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000412void Context::deleteFramebuffer(GLuint framebuffer)
413{
414 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
415
416 if (framebufferObject != mFramebufferMap.end())
417 {
418 detachFramebuffer(framebuffer);
419
420 mFramebufferHandleAllocator.release(framebufferObject->first);
421 delete framebufferObject->second;
422 mFramebufferMap.erase(framebufferObject);
423 }
424}
425
Jamie Madill33dc8432013-07-26 11:55:05 -0400426void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000427{
Jamie Madill33dc8432013-07-26 11:55:05 -0400428 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000429
Jamie Madill33dc8432013-07-26 11:55:05 -0400430 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000431 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400432 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000433 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -0400434 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000435 }
436}
437
438void Context::deleteQuery(GLuint query)
439{
440 QueryMap::iterator queryObject = mQueryMap.find(query);
441 if (queryObject != mQueryMap.end())
442 {
443 mQueryHandleAllocator.release(queryObject->first);
444 if (queryObject->second)
445 {
446 queryObject->second->release();
447 }
448 mQueryMap.erase(queryObject);
449 }
450}
451
452Buffer *Context::getBuffer(GLuint handle)
453{
454 return mResourceManager->getBuffer(handle);
455}
456
Geoff Lang48dcae72014-02-05 16:28:24 -0500457Shader *Context::getShader(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000458{
459 return mResourceManager->getShader(handle);
460}
461
Geoff Lang48dcae72014-02-05 16:28:24 -0500462Program *Context::getProgram(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000463{
464 return mResourceManager->getProgram(handle);
465}
466
Jamie Madill570f7c82014-07-03 10:38:54 -0400467Texture *Context::getTexture(GLuint handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000468{
469 return mResourceManager->getTexture(handle);
470}
471
Jamie Madill6c7b4ad2014-06-16 10:33:59 -0400472Renderbuffer *Context::getRenderbuffer(GLuint handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000473{
474 return mResourceManager->getRenderbuffer(handle);
475}
476
Jamie Madillcd055f82013-07-26 11:55:15 -0400477FenceSync *Context::getFenceSync(GLsync handle) const
478{
479 return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
480}
481
Jamie Madill57a89722013-07-02 11:57:03 -0400482VertexArray *Context::getVertexArray(GLuint handle) const
483{
484 auto vertexArray = mVertexArrayMap.find(handle);
485
486 if (vertexArray == mVertexArrayMap.end())
487 {
488 return NULL;
489 }
490 else
491 {
492 return vertexArray->second;
493 }
494}
495
Jamie Madilldc356042013-07-19 16:36:57 -0400496Sampler *Context::getSampler(GLuint handle) const
497{
498 return mResourceManager->getSampler(handle);
499}
500
Geoff Langc8058452014-02-03 12:04:11 -0500501TransformFeedback *Context::getTransformFeedback(GLuint handle) const
502{
503 if (handle == 0)
504 {
505 return mTransformFeedbackZero.get();
506 }
507 else
508 {
509 TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
510 return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
511 }
512}
513
Jamie Madilldc356042013-07-19 16:36:57 -0400514bool Context::isSampler(GLuint samplerName) const
515{
516 return mResourceManager->isSampler(samplerName);
517}
518
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000519void Context::bindArrayBuffer(unsigned int buffer)
520{
521 mResourceManager->checkBufferAllocation(buffer);
522
Shannon Woods53a94a82014-06-24 15:20:36 -0400523 mState.setArrayBufferBinding(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524}
525
526void Context::bindElementArrayBuffer(unsigned int buffer)
527{
528 mResourceManager->checkBufferAllocation(buffer);
529
Shannon Woods53a94a82014-06-24 15:20:36 -0400530 mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000531}
532
533void Context::bindTexture2D(GLuint texture)
534{
535 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
536
Shannon Woods53a94a82014-06-24 15:20:36 -0400537 mState.setSamplerTexture(TEXTURE_2D, getTexture(texture));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000538}
539
540void Context::bindTextureCubeMap(GLuint texture)
541{
542 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
543
Shannon Woods53a94a82014-06-24 15:20:36 -0400544 mState.setSamplerTexture(TEXTURE_CUBE, getTexture(texture));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000545}
546
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000547void Context::bindTexture3D(GLuint texture)
548{
549 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
550
Shannon Woods53a94a82014-06-24 15:20:36 -0400551 mState.setSamplerTexture(TEXTURE_3D, getTexture(texture));
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000552}
553
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000554void Context::bindTexture2DArray(GLuint texture)
555{
556 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
557
Shannon Woods53a94a82014-06-24 15:20:36 -0400558 mState.setSamplerTexture(TEXTURE_2D_ARRAY, getTexture(texture));
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000559}
560
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000561void Context::bindReadFramebuffer(GLuint framebuffer)
562{
563 if (!getFramebuffer(framebuffer))
564 {
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400565 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000566 }
567
Shannon Woods53a94a82014-06-24 15:20:36 -0400568 mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000569}
570
571void Context::bindDrawFramebuffer(GLuint framebuffer)
572{
573 if (!getFramebuffer(framebuffer))
574 {
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400575 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000576 }
577
Shannon Woods53a94a82014-06-24 15:20:36 -0400578 mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000579}
580
581void Context::bindRenderbuffer(GLuint renderbuffer)
582{
583 mResourceManager->checkRenderbufferAllocation(renderbuffer);
584
Shannon Woods53a94a82014-06-24 15:20:36 -0400585 mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000586}
587
Jamie Madill57a89722013-07-02 11:57:03 -0400588void Context::bindVertexArray(GLuint vertexArray)
589{
590 if (!getVertexArray(vertexArray))
591 {
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400592 VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
593 mVertexArrayMap[vertexArray] = vertexArrayObject;
Jamie Madill57a89722013-07-02 11:57:03 -0400594 }
595
Shannon Woods53a94a82014-06-24 15:20:36 -0400596 mState.setVertexArrayBinding(getVertexArray(vertexArray));
Jamie Madill57a89722013-07-02 11:57:03 -0400597}
598
Jamie Madilldc356042013-07-19 16:36:57 -0400599void Context::bindSampler(GLuint textureUnit, GLuint sampler)
600{
Shannon Woods53a94a82014-06-24 15:20:36 -0400601 ASSERT(textureUnit < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS); // TODO: Update for backend-determined array size
Jamie Madilldc356042013-07-19 16:36:57 -0400602 mResourceManager->checkSamplerAllocation(sampler);
603
Shannon Woods53a94a82014-06-24 15:20:36 -0400604 mState.setSamplerBinding(textureUnit, getSampler(sampler));
Jamie Madilldc356042013-07-19 16:36:57 -0400605}
606
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000607void Context::bindGenericUniformBuffer(GLuint buffer)
608{
609 mResourceManager->checkBufferAllocation(buffer);
610
Shannon Woods53a94a82014-06-24 15:20:36 -0400611 mState.setGenericUniformBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000612}
613
614void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000615{
616 mResourceManager->checkBufferAllocation(buffer);
617
Shannon Woods53a94a82014-06-24 15:20:36 -0400618 mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000619}
620
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000621void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
622{
623 mResourceManager->checkBufferAllocation(buffer);
624
Shannon Woods53a94a82014-06-24 15:20:36 -0400625 mState.setGenericTransformFeedbackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000626}
627
628void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000629{
630 mResourceManager->checkBufferAllocation(buffer);
631
Shannon Woods53a94a82014-06-24 15:20:36 -0400632 mState.setIndexedTransformFeedbackBufferBinding(index, getBuffer(buffer), offset, size);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000633}
634
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000635void Context::bindCopyReadBuffer(GLuint buffer)
636{
637 mResourceManager->checkBufferAllocation(buffer);
638
Shannon Woods53a94a82014-06-24 15:20:36 -0400639 mState.setCopyReadBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000640}
641
642void Context::bindCopyWriteBuffer(GLuint buffer)
643{
644 mResourceManager->checkBufferAllocation(buffer);
645
Shannon Woods53a94a82014-06-24 15:20:36 -0400646 mState.setCopyWriteBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000647}
648
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000649void Context::bindPixelPackBuffer(GLuint buffer)
650{
651 mResourceManager->checkBufferAllocation(buffer);
652
Shannon Woods53a94a82014-06-24 15:20:36 -0400653 mState.setPixelPackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000654}
655
656void Context::bindPixelUnpackBuffer(GLuint buffer)
657{
658 mResourceManager->checkBufferAllocation(buffer);
659
Shannon Woods53a94a82014-06-24 15:20:36 -0400660 mState.setPixelUnpackBufferBinding(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000661}
662
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000663void Context::useProgram(GLuint program)
664{
Shannon Woods53a94a82014-06-24 15:20:36 -0400665 GLuint priorProgramId = mState.getCurrentProgramId();
666 Program *priorProgram = mResourceManager->getProgram(priorProgramId);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000667
Shannon Woods53a94a82014-06-24 15:20:36 -0400668 if (priorProgramId != program)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000669 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400670 mState.setCurrentProgram(program, mResourceManager->getProgram(program));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000671
Shannon Woods53a94a82014-06-24 15:20:36 -0400672 if (priorProgram)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000673 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400674 priorProgram->release();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000675 }
676 }
677}
678
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000679void Context::linkProgram(GLuint program)
680{
681 Program *programObject = mResourceManager->getProgram(program);
682
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000683 bool linked = programObject->link();
684
685 // if the current program was relinked successfully we
686 // need to install the new executables
Shannon Woods53a94a82014-06-24 15:20:36 -0400687 if (linked && program == mState.getCurrentProgramId())
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000688 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400689 mState.setCurrentProgramBinary(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000690 }
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000691}
692
693void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
694{
695 Program *programObject = mResourceManager->getProgram(program);
696
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000697 bool loaded = programObject->setProgramBinary(binary, length);
698
699 // if the current program was reloaded successfully we
700 // need to install the new executables
Shannon Woods53a94a82014-06-24 15:20:36 -0400701 if (loaded && program == mState.getCurrentProgramId())
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000702 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400703 mState.setCurrentProgramBinary(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +0000704 }
705
daniel@transgaming.com95d29422012-07-24 18:36:10 +0000706}
707
Geoff Langc8058452014-02-03 12:04:11 -0500708void Context::bindTransformFeedback(GLuint transformFeedback)
709{
Shannon Woods53a94a82014-06-24 15:20:36 -0400710 mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
Geoff Langc8058452014-02-03 12:04:11 -0500711}
712
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000713void Context::beginQuery(GLenum target, GLuint query)
714{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000715 Query *queryObject = getQuery(query, true, target);
Jamie Madilldb2f14c2014-05-13 13:56:30 -0400716 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000717
718 // set query as active for specified target
Shannon Woods53a94a82014-06-24 15:20:36 -0400719 mState.setActiveQuery(target, queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000720
721 // begin query
722 queryObject->begin();
723}
724
725void Context::endQuery(GLenum target)
726{
Shannon Woods53a94a82014-06-24 15:20:36 -0400727 Query *queryObject = mState.getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -0400728 ASSERT(queryObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000729
730 queryObject->end();
731
Shannon Woods53a94a82014-06-24 15:20:36 -0400732 mState.setActiveQuery(target, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000733}
734
735void Context::setFramebufferZero(Framebuffer *buffer)
736{
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400737 // First, check to see if the old default framebuffer
738 // was set for draw or read framebuffer, and change
739 // the bindings to point to the new one before deleting it.
Shannon Woods53a94a82014-06-24 15:20:36 -0400740 if (mState.getDrawFramebuffer()->id() == 0)
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400741 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400742 mState.setDrawFramebufferBinding(buffer);
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400743 }
744
Shannon Woods53a94a82014-06-24 15:20:36 -0400745 if (mState.getReadFramebuffer()->id() == 0)
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400746 {
Shannon Woods53a94a82014-06-24 15:20:36 -0400747 mState.setReadFramebufferBinding(buffer);
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -0400748 }
749
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000750 delete mFramebufferMap[0];
751 mFramebufferMap[0] = buffer;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000752}
753
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000754void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000755{
Geoff Langc0b9ef42014-07-02 10:02:37 -0400756 const TextureCaps &formatCaps = getTextureCaps().get(internalformat);
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400757
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000758 RenderbufferStorage *renderbuffer = NULL;
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400759
Geoff Langcec35902014-04-16 10:52:36 -0400760 if (formatCaps.colorRendering)
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000761 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000762 renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400763 }
Geoff Langcec35902014-04-16 10:52:36 -0400764 else if (formatCaps.depthRendering && formatCaps.stencilRendering)
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400765 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000766 renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400767 }
Geoff Langcec35902014-04-16 10:52:36 -0400768 else if (formatCaps.depthRendering)
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400769 {
770 renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
771 }
Geoff Langcec35902014-04-16 10:52:36 -0400772 else if (formatCaps.stencilRendering)
Geoff Lang2e1dcd52013-05-29 10:34:08 -0400773 {
774 renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
775 }
776 else
777 {
778 UNREACHABLE();
779 return;
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000780 }
781
Shannon Woods53a94a82014-06-24 15:20:36 -0400782 mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000783}
784
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500785Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000786{
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500787 FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000788
789 if (framebuffer == mFramebufferMap.end())
790 {
791 return NULL;
792 }
793 else
794 {
795 return framebuffer->second;
796 }
797}
798
Jamie Madill33dc8432013-07-26 11:55:05 -0400799FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000800{
Jamie Madill33dc8432013-07-26 11:55:05 -0400801 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000802
Jamie Madill33dc8432013-07-26 11:55:05 -0400803 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000804 {
805 return NULL;
806 }
807 else
808 {
809 return fence->second;
810 }
811}
812
813Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
814{
815 QueryMap::iterator query = mQueryMap.find(handle);
816
817 if (query == mQueryMap.end())
818 {
819 return NULL;
820 }
821 else
822 {
823 if (!query->second && create)
824 {
shannon.woods@transgaming.comb32e1982013-02-28 23:02:59 +0000825 query->second = new Query(mRenderer, type, handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826 query->second->addRef();
827 }
828 return query->second;
829 }
830}
831
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500832Texture *Context::getTargetTexture(GLenum target) const
833{
834 if (!ValidTextureTarget(this, target))
835 {
836 return NULL;
837 }
838
839 switch (target)
840 {
841 case GL_TEXTURE_2D: return getTexture2D();
842 case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
843 case GL_TEXTURE_3D: return getTexture3D();
844 case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
845 default: return NULL;
846 }
847}
848
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500849Texture2D *Context::getTexture2D() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000850{
Shannon Woods53a94a82014-06-24 15:20:36 -0400851 return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000852}
853
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500854TextureCubeMap *Context::getTextureCubeMap() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000855{
Shannon Woods53a94a82014-06-24 15:20:36 -0400856 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_CUBE));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000857}
858
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500859Texture3D *Context::getTexture3D() const
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000860{
Shannon Woods53a94a82014-06-24 15:20:36 -0400861 return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_3D));
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000862}
863
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500864Texture2DArray *Context::getTexture2DArray() const
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000865{
Shannon Woods53a94a82014-06-24 15:20:36 -0400866 return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D_ARRAY));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000867}
868
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500869Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000870{
Shannon Woods53a94a82014-06-24 15:20:36 -0400871 if (mState.getSamplerTextureId(sampler, type) == 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000872 {
873 switch (type)
874 {
875 default: UNREACHABLE();
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000876 case TEXTURE_2D: return mTexture2DZero.get();
877 case TEXTURE_CUBE: return mTextureCubeMapZero.get();
878 case TEXTURE_3D: return mTexture3DZero.get();
879 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000880 }
881 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400882 else
883 {
884 return mState.getSamplerTexture(sampler, type);
885 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000886}
887
Jamie Madill893ab082014-05-16 16:56:10 -0400888void Context::getBooleanv(GLenum pname, GLboolean *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000889{
890 switch (pname)
891 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000892 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000893 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000894 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400895 mState.getBooleanv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400896 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000897 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000898}
899
Jamie Madill893ab082014-05-16 16:56:10 -0400900void Context::getFloatv(GLenum pname, GLfloat *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000901{
Shannon Woods53a94a82014-06-24 15:20:36 -0400902 // Queries about context capabilities and maximums are answered by Context.
903 // Queries about current GL state values are answered by State.
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000904 switch (pname)
905 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000906 case GL_ALIASED_LINE_WIDTH_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400907 params[0] = mCaps.minAliasedLineWidth;
908 params[1] = mCaps.maxAliasedLineWidth;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000909 break;
910 case GL_ALIASED_POINT_SIZE_RANGE:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400911 params[0] = mCaps.minAliasedPointSize;
912 params[1] = mCaps.maxAliasedPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000913 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000914 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -0400915 ASSERT(mExtensions.textureFilterAnisotropic);
916 *params = mExtensions.maxTextureAnisotropy;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000917 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000918 default:
Shannon Woods53a94a82014-06-24 15:20:36 -0400919 mState.getFloatv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -0400920 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000921 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000922}
923
Jamie Madill893ab082014-05-16 16:56:10 -0400924void Context::getIntegerv(GLenum pname, GLint *params)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000925{
Shannon Woods53a94a82014-06-24 15:20:36 -0400926 // Queries about context capabilities and maximums are answered by Context.
927 // Queries about current GL state values are answered by State.
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +0000928
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000929 switch (pname)
930 {
Jamie Madill1caff072013-07-19 16:36:56 -0400931 case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
932 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
933 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break;
934 case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
Geoff Langd3ff9002014-05-08 11:19:27 -0400935 case GL_MAX_VARYING_COMPONENTS: *params = mRenderer->getMaxVaryingVectors() * 4; break;
Jamie Madill1caff072013-07-19 16:36:56 -0400936 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
937 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
938 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
939 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
940 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400941 case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
942 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
943 case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
Jamie Madill1caff072013-07-19 16:36:56 -0400944 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
945 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
Jamie Madill1caff072013-07-19 16:36:56 -0400946 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
Jamie Madill1caff072013-07-19 16:36:56 -0400947 case GL_SUBPIXEL_BITS: *params = 4; break;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400948 case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
949 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
950 case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
951 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
Jamie Madill1caff072013-07-19 16:36:56 -0400952 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break;
953 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break;
954 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break;
955 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break;
956 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break;
Jamie Madillee7010d2013-10-17 10:45:47 -0400957 case GL_MAJOR_VERSION: *params = mClientVersion; break;
958 case GL_MINOR_VERSION: *params = 0; break;
Jamie Madill13a2f852013-12-11 16:35:08 -0500959 case GL_MAX_ELEMENTS_INDICES: *params = mRenderer->getMaxRecommendedElementsIndices(); break;
960 case GL_MAX_ELEMENTS_VERTICES: *params = mRenderer->getMaxRecommendedElementsVertices(); break;
Geoff Lang1b6edcb2014-02-03 14:27:56 -0500961 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
962 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mRenderer->getMaxTransformFeedbackBuffers(); break;
963 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackSeparateComponents(); break;
Jamie Madill893ab082014-05-16 16:56:10 -0400964 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000965 params[0] = mNumCompressedTextureFormats;
966 break;
967 case GL_MAX_SAMPLES_ANGLE:
Jamie Madill893ab082014-05-16 16:56:10 -0400968 *params = static_cast<GLint>(getMaxSupportedSamples());
969 break;
daniel@transgaming.com42944b02012-09-27 17:45:57 +0000970 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
971 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
972 {
Geoff Lang005df412013-10-16 14:12:50 -0400973 GLenum internalFormat, format, type;
Jamie Madill893ab082014-05-16 16:56:10 -0400974 getCurrentReadFormatType(&internalFormat, &format, &type);
975 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
976 *params = format;
977 else
978 *params = type;
daniel@transgaming.com42944b02012-09-27 17:45:57 +0000979 }
980 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000981 case GL_MAX_VIEWPORT_DIMS:
982 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400983 params[0] = mCaps.maxViewportWidth;
984 params[1] = mCaps.maxViewportHeight;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000985 }
986 break;
987 case GL_COMPRESSED_TEXTURE_FORMATS:
988 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400989 if (mExtensions.textureCompressionDXT1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000990 {
991 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
992 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
993 }
Geoff Langc0b9ef42014-07-02 10:02:37 -0400994 if (mExtensions.textureCompressionDXT3)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000995 {
996 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
997 }
Geoff Langc0b9ef42014-07-02 10:02:37 -0400998 if (mExtensions.textureCompressionDXT5)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999 {
1000 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1001 }
1002 }
1003 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001004 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1005 *params = mResetStrategy;
1006 break;
1007 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1008 *params = 1;
1009 break;
1010 case GL_PROGRAM_BINARY_FORMATS_OES:
1011 *params = GL_PROGRAM_BINARY_ANGLE;
1012 break;
Geoff Lang23c81692013-08-12 10:46:58 -04001013 case GL_NUM_EXTENSIONS:
Geoff Langcec35902014-04-16 10:52:36 -04001014 *params = static_cast<GLint>(mExtensionStrings.size());
Geoff Lang23c81692013-08-12 10:46:58 -04001015 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016 default:
Shannon Woods53a94a82014-06-24 15:20:36 -04001017 mState.getIntegerv(pname, params);
Jamie Madill893ab082014-05-16 16:56:10 -04001018 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001019 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020}
1021
Jamie Madill893ab082014-05-16 16:56:10 -04001022void Context::getInteger64v(GLenum pname, GLint64 *params)
Jamie Madill0fda9862013-07-19 16:36:55 -04001023{
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 // Queries about context capabilities and maximums are answered by Context.
1025 // Queries about current GL state values are answered by State.
Jamie Madill0fda9862013-07-19 16:36:55 -04001026 switch (pname)
1027 {
1028 case GL_MAX_ELEMENT_INDEX:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001029 *params = mCaps.maxElementIndex;
Jamie Madill0fda9862013-07-19 16:36:55 -04001030 break;
1031 case GL_MAX_UNIFORM_BLOCK_SIZE:
1032 *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
1033 break;
1034 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1035 {
1036 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
1037 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
1038 *params = uniformBufferComponents + defaultBufferComponents;
1039 }
1040 break;
1041 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1042 {
1043 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
1044 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
1045 *params = uniformBufferComponents + defaultBufferComponents;
1046 }
1047 break;
1048 case GL_MAX_SERVER_WAIT_TIMEOUT:
Jamie Madill5215e1a2013-07-26 11:55:19 -04001049 // We do not wait for server fence objects internally, so report a max timeout of zero.
1050 *params = 0;
Jamie Madill0fda9862013-07-19 16:36:55 -04001051 break;
1052 default:
Jamie Madill893ab082014-05-16 16:56:10 -04001053 UNREACHABLE();
1054 break;
Jamie Madill0fda9862013-07-19 16:36:55 -04001055 }
Jamie Madill0fda9862013-07-19 16:36:55 -04001056}
1057
Shannon Woods1b2fb852013-08-19 14:28:48 -04001058bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1059{
Shannon Woods53a94a82014-06-24 15:20:36 -04001060 // Queries about context capabilities and maximums are answered by Context.
1061 // Queries about current GL state values are answered by State.
1062 // Indexed integer queries all refer to current state, so this function is a
1063 // mere passthrough.
1064 return mState.getIndexedIntegerv(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001065}
1066
1067bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1068{
Shannon Woods53a94a82014-06-24 15:20:36 -04001069 // Queries about context capabilities and maximums are answered by Context.
1070 // Queries about current GL state values are answered by State.
1071 // Indexed integer queries all refer to current state, so this function is a
1072 // mere passthrough.
1073 return mState.getIndexedInteger64v(target, index, data);
Shannon Woods1b2fb852013-08-19 14:28:48 -04001074}
1075
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001076bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1077{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001078 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1079 {
1080 *type = GL_INT;
1081 *numParams = 1;
1082 return true;
1083 }
1084
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001085 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1086 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1087 // to the fact that it is stored internally as a float, and so would require conversion
Jamie Madill893ab082014-05-16 16:56:10 -04001088 // if returned from Context::getIntegerv. Since this conversion is already implemented
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001089 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1090 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1091 // application.
1092 switch (pname)
1093 {
1094 case GL_COMPRESSED_TEXTURE_FORMATS:
1095 {
1096 *type = GL_INT;
1097 *numParams = mNumCompressedTextureFormats;
1098 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001099 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001100 case GL_SHADER_BINARY_FORMATS:
1101 {
1102 *type = GL_INT;
1103 *numParams = 0;
1104 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001105 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001106 case GL_MAX_VERTEX_ATTRIBS:
1107 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1108 case GL_MAX_VARYING_VECTORS:
1109 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1110 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1111 case GL_MAX_TEXTURE_IMAGE_UNITS:
1112 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1113 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00001114 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001115 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001116 case GL_NUM_SHADER_BINARY_FORMATS:
1117 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1118 case GL_ARRAY_BUFFER_BINDING:
Vladimir Vukicevic1e514352014-05-13 15:53:06 -07001119 //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1120 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1121 case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001122 case GL_RENDERBUFFER_BINDING:
1123 case GL_CURRENT_PROGRAM:
1124 case GL_PACK_ALIGNMENT:
1125 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1126 case GL_UNPACK_ALIGNMENT:
1127 case GL_GENERATE_MIPMAP_HINT:
1128 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1129 case GL_RED_BITS:
1130 case GL_GREEN_BITS:
1131 case GL_BLUE_BITS:
1132 case GL_ALPHA_BITS:
1133 case GL_DEPTH_BITS:
1134 case GL_STENCIL_BITS:
1135 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1136 case GL_CULL_FACE_MODE:
1137 case GL_FRONT_FACE:
1138 case GL_ACTIVE_TEXTURE:
1139 case GL_STENCIL_FUNC:
1140 case GL_STENCIL_VALUE_MASK:
1141 case GL_STENCIL_REF:
1142 case GL_STENCIL_FAIL:
1143 case GL_STENCIL_PASS_DEPTH_FAIL:
1144 case GL_STENCIL_PASS_DEPTH_PASS:
1145 case GL_STENCIL_BACK_FUNC:
1146 case GL_STENCIL_BACK_VALUE_MASK:
1147 case GL_STENCIL_BACK_REF:
1148 case GL_STENCIL_BACK_FAIL:
1149 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1150 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1151 case GL_DEPTH_FUNC:
1152 case GL_BLEND_SRC_RGB:
1153 case GL_BLEND_SRC_ALPHA:
1154 case GL_BLEND_DST_RGB:
1155 case GL_BLEND_DST_ALPHA:
1156 case GL_BLEND_EQUATION_RGB:
1157 case GL_BLEND_EQUATION_ALPHA:
1158 case GL_STENCIL_WRITEMASK:
1159 case GL_STENCIL_BACK_WRITEMASK:
1160 case GL_STENCIL_CLEAR_VALUE:
1161 case GL_SUBPIXEL_BITS:
1162 case GL_MAX_TEXTURE_SIZE:
1163 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1164 case GL_SAMPLE_BUFFERS:
1165 case GL_SAMPLES:
1166 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1167 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1168 case GL_TEXTURE_BINDING_2D:
1169 case GL_TEXTURE_BINDING_CUBE_MAP:
1170 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1171 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1172 case GL_PROGRAM_BINARY_FORMATS_OES:
1173 {
1174 *type = GL_INT;
1175 *numParams = 1;
1176 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001177 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001178 case GL_MAX_SAMPLES_ANGLE:
1179 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001180 if (mExtensions.framebufferMultisample)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001181 {
1182 *type = GL_INT;
1183 *numParams = 1;
1184 }
1185 else
1186 {
1187 return false;
1188 }
1189 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001190 return true;
Shannon Woods158c4382014-05-06 13:00:07 -04001191 case GL_PIXEL_PACK_BUFFER_BINDING:
1192 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1193 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001194 if (mExtensions.pixelBufferObject)
Shannon Woods158c4382014-05-06 13:00:07 -04001195 {
1196 *type = GL_INT;
1197 *numParams = 1;
1198 }
1199 else
1200 {
1201 return false;
1202 }
1203 }
1204 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001205 case GL_MAX_VIEWPORT_DIMS:
1206 {
1207 *type = GL_INT;
1208 *numParams = 2;
1209 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001210 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001211 case GL_VIEWPORT:
1212 case GL_SCISSOR_BOX:
1213 {
1214 *type = GL_INT;
1215 *numParams = 4;
1216 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001217 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001218 case GL_SHADER_COMPILER:
1219 case GL_SAMPLE_COVERAGE_INVERT:
1220 case GL_DEPTH_WRITEMASK:
1221 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1222 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1223 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1224 case GL_SAMPLE_COVERAGE:
1225 case GL_SCISSOR_TEST:
1226 case GL_STENCIL_TEST:
1227 case GL_DEPTH_TEST:
1228 case GL_BLEND:
1229 case GL_DITHER:
1230 case GL_CONTEXT_ROBUST_ACCESS_EXT:
1231 {
1232 *type = GL_BOOL;
1233 *numParams = 1;
1234 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001235 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001236 case GL_COLOR_WRITEMASK:
1237 {
1238 *type = GL_BOOL;
1239 *numParams = 4;
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_POLYGON_OFFSET_FACTOR:
1243 case GL_POLYGON_OFFSET_UNITS:
1244 case GL_SAMPLE_COVERAGE_VALUE:
1245 case GL_DEPTH_CLEAR_VALUE:
1246 case GL_LINE_WIDTH:
1247 {
1248 *type = GL_FLOAT;
1249 *numParams = 1;
1250 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001251 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001252 case GL_ALIASED_LINE_WIDTH_RANGE:
1253 case GL_ALIASED_POINT_SIZE_RANGE:
1254 case GL_DEPTH_RANGE:
1255 {
1256 *type = GL_FLOAT;
1257 *numParams = 2;
1258 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001259 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001260 case GL_COLOR_CLEAR_VALUE:
1261 case GL_BLEND_COLOR:
1262 {
1263 *type = GL_FLOAT;
1264 *numParams = 4;
1265 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001266 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001267 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
Geoff Langc0b9ef42014-07-02 10:02:37 -04001268 if (!mExtensions.maxTextureAnisotropy)
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001269 {
1270 return false;
1271 }
1272 *type = GL_FLOAT;
1273 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001274 return true;
1275 }
1276
1277 if (mClientVersion < 3)
1278 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001279 return false;
1280 }
1281
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001282 // Check for ES3.0+ parameter names
1283 switch (pname)
1284 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00001285 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1286 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001287 case GL_UNIFORM_BUFFER_BINDING:
1288 case GL_TRANSFORM_FEEDBACK_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001289 case GL_COPY_READ_BUFFER_BINDING:
1290 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001291 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001292 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00001293 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00001294 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00001295 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1296 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1297 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Geoff Langd3ff9002014-05-08 11:19:27 -04001298 case GL_MAX_VARYING_COMPONENTS:
Jamie Madillefb3bd12013-07-02 11:57:05 -04001299 case GL_VERTEX_ARRAY_BINDING:
Jamie Madill38850df2013-07-19 16:36:55 -04001300 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1301 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang23c81692013-08-12 10:46:58 -04001302 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04001303 case GL_MAJOR_VERSION:
1304 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05001305 case GL_MAX_ELEMENTS_INDICES:
1306 case GL_MAX_ELEMENTS_VERTICES:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001307 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
Jamie Madill2e503552013-12-19 13:48:34 -05001308 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001309 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001310 {
1311 *type = GL_INT;
1312 *numParams = 1;
1313 }
1314 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04001315
1316 case GL_MAX_ELEMENT_INDEX:
1317 case GL_MAX_UNIFORM_BLOCK_SIZE:
1318 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1319 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1320 case GL_MAX_SERVER_WAIT_TIMEOUT:
1321 {
1322 *type = GL_INT_64_ANGLEX;
1323 *numParams = 1;
1324 }
1325 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05001326
1327 case GL_TRANSFORM_FEEDBACK_ACTIVE:
Geoff Lang1b6edcb2014-02-03 14:27:56 -05001328 case GL_TRANSFORM_FEEDBACK_PAUSED:
Jamie Madill2e503552013-12-19 13:48:34 -05001329 {
1330 *type = GL_BOOL;
1331 *numParams = 1;
1332 }
1333 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001334 }
1335
1336 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001337}
1338
Shannon Woods1b2fb852013-08-19 14:28:48 -04001339bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1340{
1341 if (mClientVersion < 3)
1342 {
1343 return false;
1344 }
1345
1346 switch (target)
1347 {
1348 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1349 case GL_UNIFORM_BUFFER_BINDING:
1350 {
1351 *type = GL_INT;
1352 *numParams = 1;
1353 }
1354 return true;
1355 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1356 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1357 case GL_UNIFORM_BUFFER_START:
1358 case GL_UNIFORM_BUFFER_SIZE:
1359 {
1360 *type = GL_INT_64_ANGLEX;
1361 *numParams = 1;
1362 }
1363 }
1364
1365 return false;
1366}
1367
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001368// Applies the render target surface, depth stencil surface, viewport rectangle and
daniel@transgaming.com12985182012-12-20 20:56:31 +00001369// scissor rectangle to the renderer
1370bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001371{
Shannon Woods53a94a82014-06-24 15:20:36 -04001372 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
Jamie Madill13f7d7d2014-06-20 13:21:27 -04001373 ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001374
daniel@transgaming.com8a8b24c2012-11-28 19:36:26 +00001375 mRenderer->applyRenderTarget(framebufferObject);
1376
Shannon Woods53a94a82014-06-24 15:20:36 -04001377 float nearZ, farZ;
1378 mState.getDepthRange(&nearZ, &farZ);
1379 if (!mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
shannon.woods@transgaming.com0b236e22013-01-25 21:57:07 +00001380 ignoreViewport))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001381 {
daniel@transgaming.com3ca082c2012-11-28 19:41:07 +00001382 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001383 }
1384
Shannon Woods53a94a82014-06-24 15:20:36 -04001385 mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001386
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001387 return true;
1388}
1389
1390// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
1391void Context::applyState(GLenum drawMode)
1392{
Shannon Woods53a94a82014-06-24 15:20:36 -04001393 Framebuffer *framebufferObject = mState.getDrawFramebuffer();
Nicolas Capensfd396552013-06-18 21:41:30 -04001394 int samples = framebufferObject->getSamples();
1395
Shannon Woods53a94a82014-06-24 15:20:36 -04001396 RasterizerState rasterizer = mState.getRasterizerState();
1397 rasterizer.pointDrawMode = (drawMode == GL_POINTS);
1398 rasterizer.multiSample = (samples != 0);
1399
1400 mRenderer->setRasterizerState(rasterizer);
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001401
1402 unsigned int mask = 0;
Shannon Woods53a94a82014-06-24 15:20:36 -04001403 if (mState.isSampleCoverageEnabled())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001404 {
Shannon Woods53a94a82014-06-24 15:20:36 -04001405 GLclampf coverageValue;
1406 bool coverageInvert = false;
1407 mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
1408 if (coverageValue != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001409 {
Jamie Madill893ab082014-05-16 16:56:10 -04001410
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001411 float threshold = 0.5f;
1412
Nicolas Capensfd396552013-06-18 21:41:30 -04001413 for (int i = 0; i < samples; ++i)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001414 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001415 mask <<= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001416
Shannon Woods53a94a82014-06-24 15:20:36 -04001417 if ((i + 1) * coverageValue >= threshold)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001418 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001419 threshold += 1.0f;
1420 mask |= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001421 }
1422 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001423 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001424
Shannon Woods53a94a82014-06-24 15:20:36 -04001425 if (coverageInvert)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001426 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001427 mask = ~mask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001428 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001429 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001430 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001431 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001432 mask = 0xFFFFFFFF;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001433 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001434 mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
daniel@transgaming.com2e258642012-11-28 19:36:18 +00001435
Shannon Woods53a94a82014-06-24 15:20:36 -04001436 mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
1437 rasterizer.frontFace == GL_CCW);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001438}
1439
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001440// Applies the shaders and shader constants to the Direct3D 9 device
Geoff Lang4c5c6bb2014-02-05 16:32:46 -05001441void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001442{
Shannon Woods53a94a82014-06-24 15:20:36 -04001443 const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
Jamie Madillc5a83002014-02-14 16:41:25 -05001444
1445 VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
Shannon Woods53a94a82014-06-24 15:20:36 -04001446 VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
Jamie Madillc5a83002014-02-14 16:41:25 -05001447
Shannon Woods53a94a82014-06-24 15:20:36 -04001448 const Framebuffer *fbo = mState.getDrawFramebuffer();
Geoff Lang04fb89a2014-06-09 15:05:36 -04001449
Shannon Woods53a94a82014-06-24 15:20:36 -04001450 mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
Geoff Lang0550d032014-01-30 11:29:07 -05001451
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001452 programBinary->applyUniforms();
1453}
1454
Geoff Lang43b00422014-05-12 16:28:07 -04001455size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
1456 TextureType *outTextureTypes, SamplerState *outSamplers)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001457{
Geoff Lang43b00422014-05-12 16:28:07 -04001458 size_t samplerRange = programBinary->getUsedSamplerRange(type);
1459 for (size_t i = 0; i < samplerRange; i++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001460 {
Geoff Lang43b00422014-05-12 16:28:07 -04001461 outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
1462 GLint textureUnit = programBinary->getSamplerMapping(type, i); // OpenGL texture image unit index
1463 if (textureUnit != -1)
Geoff Lange2e0ce02013-09-17 17:05:08 -04001464 {
Geoff Lang43b00422014-05-12 16:28:07 -04001465 outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
Brandon Jonesa328d562014-07-01 13:52:40 -07001466 outTextures[i]->getSamplerStateWithNativeOffset(&outSamplers[i]);
Shannon Woods53a94a82014-06-24 15:20:36 -04001467 Sampler *samplerObject = mState.getSampler(textureUnit);
1468 if (samplerObject)
Geoff Lang43b00422014-05-12 16:28:07 -04001469 {
Geoff Lang43b00422014-05-12 16:28:07 -04001470 samplerObject->getState(&outSamplers[i]);
1471 }
Geoff Lange2e0ce02013-09-17 17:05:08 -04001472 }
Geoff Lang43b00422014-05-12 16:28:07 -04001473 else
Geoff Lange2e0ce02013-09-17 17:05:08 -04001474 {
Geoff Lang43b00422014-05-12 16:28:07 -04001475 outTextures[i] = NULL;
Geoff Lange2e0ce02013-09-17 17:05:08 -04001476 }
1477 }
Geoff Lang43b00422014-05-12 16:28:07 -04001478
1479 return samplerRange;
Geoff Lange2e0ce02013-09-17 17:05:08 -04001480}
1481
Geoff Lang43b00422014-05-12 16:28:07 -04001482void Context::generateSwizzles(Texture *textures[], size_t count)
Geoff Lange2e0ce02013-09-17 17:05:08 -04001483{
Geoff Lang43b00422014-05-12 16:28:07 -04001484 for (size_t i = 0; i < count; i++)
Geoff Lange2e0ce02013-09-17 17:05:08 -04001485 {
Brandon Jonesa328d562014-07-01 13:52:40 -07001486 if (textures[i] && textures[i]->getSamplerState().swizzleRequired())
Geoff Lang43b00422014-05-12 16:28:07 -04001487 {
1488 mRenderer->generateSwizzle(textures[i]);
1489 }
Geoff Lange2e0ce02013-09-17 17:05:08 -04001490 }
1491}
1492
1493// For each Direct3D sampler of either the pixel or vertex stage,
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001494// looks up the corresponding OpenGL texture image unit and texture type,
1495// and sets the texture and its addressing/filtering state (or NULL when inactive).
Geoff Lang43b00422014-05-12 16:28:07 -04001496void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
1497 size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
1498 size_t framebufferSerialCount)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001499{
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +00001500 // Range of Direct3D samplers of given sampler type
Geoff Lang43b00422014-05-12 16:28:07 -04001501 size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
1502 : mRenderer->getMaxVertexTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001503
Geoff Lang43b00422014-05-12 16:28:07 -04001504 for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001505 {
Geoff Lang43b00422014-05-12 16:28:07 -04001506 Texture *texture = textures[samplerIndex];
1507 const SamplerState &sampler = samplers[samplerIndex];
1508 TextureType textureType = textureTypes[samplerIndex];
1509
1510 if (texture)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001511 {
Geoff Lang43b00422014-05-12 16:28:07 -04001512 // TODO: std::binary_search may become unavailable using older versions of GCC
1513 if (texture->isSamplerComplete(sampler) &&
1514 !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001515 {
Geoff Lang43b00422014-05-12 16:28:07 -04001516 mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
1517 mRenderer->setTexture(shaderType, samplerIndex, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001518 texture->resetDirty();
1519 }
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00001520 else
1521 {
Geoff Lang43b00422014-05-12 16:28:07 -04001522 Texture *incompleteTexture = getIncompleteTexture(textureType);
1523 mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
1524 incompleteTexture->resetDirty();
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00001525 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001526 }
1527 else
1528 {
Geoff Lang43b00422014-05-12 16:28:07 -04001529 mRenderer->setTexture(shaderType, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001530 }
1531 }
1532
Geoff Lang43b00422014-05-12 16:28:07 -04001533 for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001534 {
Geoff Lang43b00422014-05-12 16:28:07 -04001535 mRenderer->setTexture(shaderType, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001536 }
1537}
1538
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001539bool Context::applyUniformBuffers()
1540{
Shannon Woods53a94a82014-06-24 15:20:36 -04001541 Program *programObject = getProgram(mState.getCurrentProgramId());
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001542 ProgramBinary *programBinary = programObject->getProgramBinary();
1543
1544 std::vector<gl::Buffer*> boundBuffers;
1545
1546 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
1547 {
1548 GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
Shannon Woods53a94a82014-06-24 15:20:36 -04001549
1550 if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001551 {
1552 // undefined behaviour
1553 return false;
1554 }
1555 else
1556 {
Shannon Woods53a94a82014-06-24 15:20:36 -04001557 Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001558 ASSERT(uniformBuffer);
1559 boundBuffers.push_back(uniformBuffer);
1560 }
1561 }
1562
1563 return programBinary->applyUniformBuffers(boundBuffers);
1564}
1565
Geoff Langeeba6e12014-02-03 13:12:30 -05001566bool Context::applyTransformFeedbackBuffers()
1567{
Shannon Woods53a94a82014-06-24 15:20:36 -04001568 TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
Geoff Langeeba6e12014-02-03 13:12:30 -05001569 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
1570 {
1571 Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1572 GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1573 for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1574 {
Shannon Woods53a94a82014-06-24 15:20:36 -04001575 transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
1576 transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
Geoff Langeeba6e12014-02-03 13:12:30 -05001577 }
1578 mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
1579 return true;
1580 }
1581 else
1582 {
1583 return false;
1584 }
1585}
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001586
Geoff Langeeba6e12014-02-03 13:12:30 -05001587void Context::markTransformFeedbackUsage()
1588{
1589 for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1590 {
Shannon Woods53a94a82014-06-24 15:20:36 -04001591 Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
Geoff Langeeba6e12014-02-03 13:12:30 -05001592 if (buffer)
1593 {
1594 buffer->markTransformFeedbackUsage();
1595 }
1596 }
1597}
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001598
1599void Context::clear(GLbitfield mask)
1600{
Shannon Woods53a94a82014-06-24 15:20:36 -04001601 if (mState.isRasterizerDiscardEnabled())
Geoff Lang0550d032014-01-30 11:29:07 -05001602 {
1603 return;
1604 }
1605
Shannon Woods53a94a82014-06-24 15:20:36 -04001606 ClearParameters clearParams = mState.getClearParameters(mask);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001607
daniel@transgaming.com12985182012-12-20 20:56:31 +00001608 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001609 {
1610 return;
1611 }
1612
Shannon Woods53a94a82014-06-24 15:20:36 -04001613 mRenderer->clear(clearParams, mState.getDrawFramebuffer());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001614}
1615
Geoff Lang42359ca2013-08-21 13:25:17 -04001616void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
1617{
Shannon Woods53a94a82014-06-24 15:20:36 -04001618 if (mState.isRasterizerDiscardEnabled())
Geoff Lang0550d032014-01-30 11:29:07 -05001619 {
1620 return;
1621 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001622
Geoff Lang0550d032014-01-30 11:29:07 -05001623 // glClearBufferfv can be called to clear the color buffer or depth buffer
Shannon Woods53a94a82014-06-24 15:20:36 -04001624 ClearParameters clearParams = mState.getClearParameters(0);
Geoff Lang42359ca2013-08-21 13:25:17 -04001625
1626 if (buffer == GL_COLOR)
1627 {
1628 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1629 {
1630 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1631 }
1632 clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
1633 clearParams.colorClearType = GL_FLOAT;
1634 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001635
1636 if (buffer == GL_DEPTH)
1637 {
1638 clearParams.clearDepth = true;
1639 clearParams.depthClearValue = values[0];
1640 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001641
1642 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
1643 {
1644 return;
1645 }
1646
Shannon Woods53a94a82014-06-24 15:20:36 -04001647 mRenderer->clear(clearParams, mState.getDrawFramebuffer());
Geoff Lang42359ca2013-08-21 13:25:17 -04001648}
1649
1650void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
1651{
Shannon Woods53a94a82014-06-24 15:20:36 -04001652 if (mState.isRasterizerDiscardEnabled())
Geoff Lang0550d032014-01-30 11:29:07 -05001653 {
1654 return;
1655 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001656
Geoff Lang0550d032014-01-30 11:29:07 -05001657 // glClearBufferuv can only be called to clear a color buffer
Shannon Woods53a94a82014-06-24 15:20:36 -04001658 ClearParameters clearParams = mState.getClearParameters(0);
Geoff Lang42359ca2013-08-21 13:25:17 -04001659 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1660 {
1661 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1662 }
1663 clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
1664 clearParams.colorClearType = GL_UNSIGNED_INT;
Geoff Lang42359ca2013-08-21 13:25:17 -04001665
1666 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
1667 {
1668 return;
1669 }
1670
Shannon Woods53a94a82014-06-24 15:20:36 -04001671 mRenderer->clear(clearParams, mState.getDrawFramebuffer());
Geoff Lang42359ca2013-08-21 13:25:17 -04001672}
1673
1674void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
1675{
Shannon Woods53a94a82014-06-24 15:20:36 -04001676 if (mState.isRasterizerDiscardEnabled())
Geoff Lang0550d032014-01-30 11:29:07 -05001677 {
1678 return;
1679 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001680
Geoff Lang0550d032014-01-30 11:29:07 -05001681 // glClearBufferfv can be called to clear the color buffer or stencil buffer
Shannon Woods53a94a82014-06-24 15:20:36 -04001682 ClearParameters clearParams = mState.getClearParameters(0);
Geoff Lang42359ca2013-08-21 13:25:17 -04001683
1684 if (buffer == GL_COLOR)
1685 {
1686 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1687 {
1688 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1689 }
1690 clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
1691 clearParams.colorClearType = GL_INT;
1692 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001693
1694 if (buffer == GL_STENCIL)
1695 {
1696 clearParams.clearStencil = true;
1697 clearParams.stencilClearValue = values[1];
1698 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001699
1700 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
1701 {
1702 return;
1703 }
1704
Shannon Woods53a94a82014-06-24 15:20:36 -04001705 mRenderer->clear(clearParams, mState.getDrawFramebuffer());
Geoff Lang42359ca2013-08-21 13:25:17 -04001706}
1707
1708void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
1709{
Shannon Woods53a94a82014-06-24 15:20:36 -04001710 if (mState.isRasterizerDiscardEnabled())
Geoff Lang0550d032014-01-30 11:29:07 -05001711 {
1712 return;
1713 }
Geoff Lang42359ca2013-08-21 13:25:17 -04001714
Geoff Lang0550d032014-01-30 11:29:07 -05001715 // glClearBufferfi can only be called to clear a depth stencil buffer
Shannon Woods53a94a82014-06-24 15:20:36 -04001716 ClearParameters clearParams = mState.getClearParameters(0);
Geoff Lang42359ca2013-08-21 13:25:17 -04001717 clearParams.clearDepth = true;
1718 clearParams.depthClearValue = depth;
1719 clearParams.clearStencil = true;
1720 clearParams.stencilClearValue = stencil;
Geoff Lang42359ca2013-08-21 13:25:17 -04001721
1722 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
1723 {
1724 return;
1725 }
1726
Shannon Woods53a94a82014-06-24 15:20:36 -04001727 mRenderer->clear(clearParams, mState.getDrawFramebuffer());
Geoff Lang42359ca2013-08-21 13:25:17 -04001728}
1729
1730void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1731 GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
1732{
Shannon Woods53a94a82014-06-24 15:20:36 -04001733 gl::Framebuffer *framebuffer = mState.getReadFramebuffer();
Geoff Lang42359ca2013-08-21 13:25:17 -04001734
Geoff Lange4a492b2014-06-19 14:14:41 -04001735 bool isSized = IsSizedInternalFormat(format);
1736 GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type));
Shannon Woods53a94a82014-06-24 15:20:36 -04001737 GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, width, mState.getPackAlignment());
Geoff Lang42359ca2013-08-21 13:25:17 -04001738
Shannon Woods53a94a82014-06-24 15:20:36 -04001739 mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), pixels);
Geoff Lang42359ca2013-08-21 13:25:17 -04001740}
1741
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001742void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
1743{
Shannon Woods53a94a82014-06-24 15:20:36 -04001744 ASSERT(mState.getCurrentProgramId() != 0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001745
Shannon Woods53a94a82014-06-24 15:20:36 -04001746 ProgramBinary *programBinary = mState.getCurrentProgramBinary();
Jamie Madilld4cfa572014-07-08 10:00:32 -04001747 programBinary->updateSamplerMapping();
Geoff Lange2e0ce02013-09-17 17:05:08 -04001748
Geoff Lang43b00422014-05-12 16:28:07 -04001749 Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1750 TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1751 SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1752 size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
1753
1754 Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
1755 TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
1756 SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
1757 size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
1758
1759 generateSwizzles(vsTextures, vsTextureCount);
1760 generateSwizzles(psTextures, psTextureCount);
Geoff Lange2e0ce02013-09-17 17:05:08 -04001761
daniel@transgaming.com91207b72012-11-28 20:56:43 +00001762 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001763 {
1764 return;
1765 }
1766
daniel@transgaming.com12985182012-12-20 20:56:31 +00001767 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001768 {
1769 return;
1770 }
1771
1772 applyState(mode);
1773
Shannon Woods53a94a82014-06-24 15:20:36 -04001774 GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001775 if (err != GL_NO_ERROR)
1776 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001777 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001778 }
1779
Geoff Langeeba6e12014-02-03 13:12:30 -05001780 bool transformFeedbackActive = applyTransformFeedbackBuffers();
1781
Geoff Lang4c5c6bb2014-02-05 16:32:46 -05001782 applyShaders(programBinary, transformFeedbackActive);
Geoff Lang43b00422014-05-12 16:28:07 -04001783
1784 FramebufferTextureSerialArray frameBufferSerials;
1785 size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
1786
1787 applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
1788 applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001789
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001790 if (!applyUniformBuffers())
1791 {
1792 return;
1793 }
1794
daniel@transgaming.com087e5782012-09-17 21:28:47 +00001795 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001796 {
Geoff Lang4c5c6bb2014-02-05 16:32:46 -05001797 mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
Geoff Langeeba6e12014-02-03 13:12:30 -05001798
1799 if (transformFeedbackActive)
1800 {
1801 markTransformFeedbackUsage();
1802 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001803 }
1804}
1805
1806void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
1807{
Shannon Woods53a94a82014-06-24 15:20:36 -04001808 ASSERT(mState.getCurrentProgramId() != 0);
Geoff Lange2e0ce02013-09-17 17:05:08 -04001809
Shannon Woods53a94a82014-06-24 15:20:36 -04001810 ProgramBinary *programBinary = mState.getCurrentProgramBinary();
Jamie Madilld4cfa572014-07-08 10:00:32 -04001811 programBinary->updateSamplerMapping();
Geoff Lange2e0ce02013-09-17 17:05:08 -04001812
Geoff Lang43b00422014-05-12 16:28:07 -04001813 Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1814 TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1815 SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
1816 size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
1817
1818 Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
1819 TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
1820 SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
1821 size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
1822
1823 generateSwizzles(vsTextures, vsTextureCount);
1824 generateSwizzles(psTextures, psTextureCount);
Geoff Lange2e0ce02013-09-17 17:05:08 -04001825
daniel@transgaming.com91207b72012-11-28 20:56:43 +00001826 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001827 {
1828 return;
1829 }
1830
daniel@transgaming.com12985182012-12-20 20:56:31 +00001831 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001832 {
1833 return;
1834 }
1835
1836 applyState(mode);
1837
Shannon Woods53a94a82014-06-24 15:20:36 -04001838 VertexArray *vao = mState.getVertexArray();
daniel@transgaming.com31240482012-11-28 21:06:41 +00001839 rx::TranslatedIndexData indexInfo;
Jamie Madill57a89722013-07-02 11:57:03 -04001840 GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001841 if (err != GL_NO_ERROR)
1842 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001843 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001844 }
1845
1846 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
Shannon Woods53a94a82014-06-24 15:20:36 -04001847 err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.getVertexAttribCurrentValues(), indexInfo.minIndex, vertexCount, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001848 if (err != GL_NO_ERROR)
1849 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001850 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001851 }
1852
Geoff Langeeba6e12014-02-03 13:12:30 -05001853 bool transformFeedbackActive = applyTransformFeedbackBuffers();
1854 // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
1855 // layer.
1856 ASSERT(!transformFeedbackActive);
1857
Geoff Lang4c5c6bb2014-02-05 16:32:46 -05001858 applyShaders(programBinary, transformFeedbackActive);
Geoff Lang43b00422014-05-12 16:28:07 -04001859
1860 FramebufferTextureSerialArray frameBufferSerials;
1861 size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
1862
1863 applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
1864 applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001865
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00001866 if (!applyUniformBuffers())
1867 {
1868 return;
1869 }
1870
daniel@transgaming.com087e5782012-09-17 21:28:47 +00001871 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001872 {
Jamie Madill57a89722013-07-02 11:57:03 -04001873 mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001874 }
1875}
1876
1877// Implements glFlush when block is false, glFinish when block is true
1878void Context::sync(bool block)
1879{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +00001880 mRenderer->sync(block);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001881}
1882
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001883void Context::recordInvalidEnum()
1884{
1885 mInvalidEnum = true;
1886}
1887
1888void Context::recordInvalidValue()
1889{
1890 mInvalidValue = true;
1891}
1892
1893void Context::recordInvalidOperation()
1894{
1895 mInvalidOperation = true;
1896}
1897
1898void Context::recordOutOfMemory()
1899{
1900 mOutOfMemory = true;
1901}
1902
1903void Context::recordInvalidFramebufferOperation()
1904{
1905 mInvalidFramebufferOperation = true;
1906}
1907
1908// Get one of the recorded errors and clear its flag, if any.
1909// [OpenGL ES 2.0.24] section 2.5 page 13.
1910GLenum Context::getError()
1911{
1912 if (mInvalidEnum)
1913 {
1914 mInvalidEnum = false;
1915
1916 return GL_INVALID_ENUM;
1917 }
1918
1919 if (mInvalidValue)
1920 {
1921 mInvalidValue = false;
1922
1923 return GL_INVALID_VALUE;
1924 }
1925
1926 if (mInvalidOperation)
1927 {
1928 mInvalidOperation = false;
1929
1930 return GL_INVALID_OPERATION;
1931 }
1932
1933 if (mOutOfMemory)
1934 {
1935 mOutOfMemory = false;
1936
1937 return GL_OUT_OF_MEMORY;
1938 }
1939
1940 if (mInvalidFramebufferOperation)
1941 {
1942 mInvalidFramebufferOperation = false;
1943
1944 return GL_INVALID_FRAMEBUFFER_OPERATION;
1945 }
1946
1947 return GL_NO_ERROR;
1948}
1949
1950GLenum Context::getResetStatus()
1951{
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001952 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001953 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00001954 // mResetStatus will be set by the markContextLost callback
1955 // in the case a notification is sent
1956 mRenderer->testDeviceLost(true);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001957 }
1958
1959 GLenum status = mResetStatus;
1960
1961 if (mResetStatus != GL_NO_ERROR)
1962 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00001963 ASSERT(mContextLost);
1964
daniel@transgaming.com621ce052012-10-31 17:52:29 +00001965 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001966 {
1967 mResetStatus = GL_NO_ERROR;
1968 }
1969 }
Jamie Madill893ab082014-05-16 16:56:10 -04001970
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001971 return status;
1972}
1973
1974bool Context::isResetNotificationEnabled()
1975{
1976 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1977}
1978
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00001979int Context::getClientVersion() const
1980{
1981 return mClientVersion;
1982}
1983
Geoff Langcec35902014-04-16 10:52:36 -04001984const Caps &Context::getCaps() const
1985{
Geoff Langc0b9ef42014-07-02 10:02:37 -04001986 return mCaps;
1987}
1988
1989const TextureCapsMap &Context::getTextureCaps() const
1990{
1991 return mTextureCaps;
1992}
1993
1994const Extensions &Context::getExtensions() const
1995{
1996 return mExtensions;
Geoff Langcec35902014-04-16 10:52:36 -04001997}
1998
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001999int Context::getMajorShaderModel() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002000{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00002001 return mMajorShaderModel;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002002}
2003
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002004unsigned int Context::getMaximumCombinedTextureImageUnits() const
2005{
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00002006 return mRenderer->getMaxCombinedTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002007}
2008
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00002009unsigned int Context::getMaximumCombinedUniformBufferBindings() const
2010{
2011 return mRenderer->getMaxVertexShaderUniformBuffers() +
2012 mRenderer->getMaxFragmentShaderUniformBuffers();
2013}
2014
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002015int Context::getMaxSupportedSamples() const
2016{
daniel@transgaming.comb7833982012-10-31 18:31:46 +00002017 return mRenderer->getMaxSupportedSamples();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002018}
2019
Geoff Lang005df412013-10-16 14:12:50 -04002020GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
Geoff Lang0e120e32013-05-29 10:23:55 -04002021{
2022 return mRenderer->getMaxSupportedFormatSamples(internalFormat);
2023}
2024
Geoff Lang005df412013-10-16 14:12:50 -04002025GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
Shannon Woods52f1e7e2013-07-08 10:32:17 -04002026{
2027 return mRenderer->getNumSampleCounts(internalFormat);
2028}
2029
Geoff Lang005df412013-10-16 14:12:50 -04002030void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
Shannon Woods52f1e7e2013-07-08 10:32:17 -04002031{
2032 mRenderer->getSampleCounts(internalFormat, bufSize, params);
2033}
2034
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00002035unsigned int Context::getMaxTransformFeedbackBufferBindings() const
2036{
2037 return mRenderer->getMaxTransformFeedbackBuffers();
2038}
2039
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00002040GLintptr Context::getUniformBufferOffsetAlignment() const
2041{
2042 // setting a large alignment forces uniform buffers to bind with zero offset
2043 return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
2044}
2045
Jamie Madill893ab082014-05-16 16:56:10 -04002046void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
daniel@transgaming.com42944b02012-09-27 17:45:57 +00002047{
Shannon Woods53a94a82014-06-24 15:20:36 -04002048 Framebuffer *framebuffer = mState.getReadFramebuffer();
Jamie Madill893ab082014-05-16 16:56:10 -04002049 ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00002050
Jamie Madill3c7fa222014-06-05 13:08:51 -04002051 FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
2052 ASSERT(attachment);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00002053
Jamie Madill3c7fa222014-06-05 13:08:51 -04002054 *internalFormat = attachment->getActualFormat();
Geoff Lange4a492b2014-06-19 14:14:41 -04002055 *format = gl::GetFormat(attachment->getActualFormat());
2056 *type = gl::GetType(attachment->getActualFormat());
daniel@transgaming.com42944b02012-09-27 17:45:57 +00002057}
2058
Shannon Woods53a94a82014-06-24 15:20:36 -04002059void Context::detachTexture(GLuint texture)
2060{
2061 // Simple pass-through to State's detachTexture method, as textures do not require
2062 // allocation map management either here or in the resource manager at detach time.
2063 // Zero textures are held by the Context, and we don't attempt to request them from
2064 // the State.
2065 mState.detachTexture(texture);
2066}
2067
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002068void Context::detachBuffer(GLuint buffer)
2069{
Shannon Woods53a94a82014-06-24 15:20:36 -04002070 // Buffer detachment is handled by Context, because the buffer must also be
2071 // attached from any VAOs in existence, and Context holds the VAO map.
2072
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002073 // [OpenGL ES 2.0.24] section 2.9 page 22:
2074 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2075 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2076
Shannon Woods53a94a82014-06-24 15:20:36 -04002077 mState.removeArrayBufferBinding(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002078
Jamie Madill57a89722013-07-02 11:57:03 -04002079 // mark as freed among the vertex array objects
2080 for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002081 {
Jamie Madill57a89722013-07-02 11:57:03 -04002082 vaoIt->second->detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002083 }
2084}
2085
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002086void Context::detachFramebuffer(GLuint framebuffer)
2087{
Shannon Woods53a94a82014-06-24 15:20:36 -04002088 // Framebuffer detachment is handled by Context, because 0 is a valid
2089 // Framebuffer object, and a pointer to it must be passed from Context
2090 // to State at binding time.
2091
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002092 // [OpenGL ES 2.0.24] section 4.4 page 107:
2093 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2094 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2095
Shannon Woods53a94a82014-06-24 15:20:36 -04002096 if (mState.removeReadFramebufferBinding(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002097 {
2098 bindReadFramebuffer(0);
2099 }
2100
Shannon Woods53a94a82014-06-24 15:20:36 -04002101 if (mState.removeDrawFramebufferBinding(framebuffer))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002102 {
2103 bindDrawFramebuffer(0);
2104 }
2105}
2106
2107void Context::detachRenderbuffer(GLuint renderbuffer)
2108{
Shannon Woods53a94a82014-06-24 15:20:36 -04002109 mState.detachRenderbuffer(renderbuffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002110}
2111
Jamie Madill57a89722013-07-02 11:57:03 -04002112void Context::detachVertexArray(GLuint vertexArray)
2113{
Shannon Woods53a94a82014-06-24 15:20:36 -04002114 // Vertex array detachment is handled by Context, because 0 is a valid
2115 // VAO, and a pointer to it must be passed from Context to State at
2116 // binding time.
2117
Jamie Madill57a89722013-07-02 11:57:03 -04002118 // [OpenGL ES 3.0.2] section 2.10 page 43:
2119 // If a vertex array object that is currently bound is deleted, the binding
2120 // for that object reverts to zero and the default vertex array becomes current.
Shannon Woods53a94a82014-06-24 15:20:36 -04002121 if (mState.removeVertexArrayBinding(vertexArray))
Jamie Madill57a89722013-07-02 11:57:03 -04002122 {
2123 bindVertexArray(0);
2124 }
2125}
2126
Geoff Langc8058452014-02-03 12:04:11 -05002127void Context::detachTransformFeedback(GLuint transformFeedback)
2128{
Shannon Woods53a94a82014-06-24 15:20:36 -04002129 mState.detachTransformFeedback(transformFeedback);
Geoff Langc8058452014-02-03 12:04:11 -05002130}
2131
Jamie Madilldc356042013-07-19 16:36:57 -04002132void Context::detachSampler(GLuint sampler)
2133{
Shannon Woods53a94a82014-06-24 15:20:36 -04002134 mState.detachSampler(sampler);
Jamie Madilldc356042013-07-19 16:36:57 -04002135}
2136
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002137Texture *Context::getIncompleteTexture(TextureType type)
2138{
2139 Texture *t = mIncompleteTextures[type].get();
2140
2141 if (t == NULL)
2142 {
Jamie Madill88f18f42013-09-18 14:36:19 -04002143 const GLubyte color[] = { 0, 0, 0, 255 };
2144 const PixelUnpackState incompleteUnpackState(1);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002145
2146 switch (type)
2147 {
2148 default:
2149 UNREACHABLE();
2150 // default falls through to TEXTURE_2D
2151
2152 case TEXTURE_2D:
2153 {
Brandon Jonesf47bebc2014-07-09 14:28:42 -07002154 Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture2D(), Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04002155 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002156 t = incomplete2d;
2157 }
2158 break;
2159
2160 case TEXTURE_CUBE:
2161 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +00002162 TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002163
Jamie Madill88f18f42013-09-18 14:36:19 -04002164 incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
2165 incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
2166 incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
2167 incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
2168 incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
2169 incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002170
2171 t = incompleteCube;
2172 }
2173 break;
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00002174
2175 case TEXTURE_3D:
2176 {
2177 Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04002178 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00002179
2180 t = incomplete3d;
2181 }
2182 break;
2183
2184 case TEXTURE_2D_ARRAY:
2185 {
2186 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04002187 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00002188
2189 t = incomplete2darray;
2190 }
2191 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002192 }
2193
2194 mIncompleteTextures[type].set(t);
2195 }
2196
2197 return t;
2198}
2199
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002200bool Context::skipDraw(GLenum drawMode)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002201{
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002202 if (drawMode == GL_POINTS)
2203 {
2204 // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
2205 // which affects varying interpolation. Since the value of gl_PointSize is
2206 // undefined when not written, just skip drawing to avoid unexpected results.
Shannon Woods53a94a82014-06-24 15:20:36 -04002207 if (!mState.getCurrentProgramBinary()->usesPointSize())
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002208 {
Jamie Madill893ab082014-05-16 16:56:10 -04002209 // This is stictly speaking not an error, but developers should be
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002210 // notified of risking undefined behavior.
2211 ERR("Point rendering without writing to gl_PointSize.");
2212
2213 return true;
2214 }
2215 }
daniel@transgaming.com97c852b2012-12-20 20:56:23 +00002216 else if (IsTriangleMode(drawMode))
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002217 {
Shannon Woods53a94a82014-06-24 15:20:36 -04002218 if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002219 {
2220 return true;
2221 }
2222 }
2223
2224 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002225}
2226
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002227void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2228{
Shannon Woods53a94a82014-06-24 15:20:36 -04002229 mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002230}
2231
Jamie Madille29d1672013-07-19 16:36:57 -04002232void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2233{
2234 mResourceManager->checkSamplerAllocation(sampler);
2235
2236 Sampler *samplerObject = getSampler(sampler);
2237 ASSERT(samplerObject);
2238
2239 switch (pname)
2240 {
2241 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
2242 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
2243 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
2244 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
2245 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
2246 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
2247 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
2248 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast<GLenum>(param)); break;
2249 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast<GLenum>(param)); break;
2250 default: UNREACHABLE(); break;
2251 }
2252}
2253
2254void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2255{
2256 mResourceManager->checkSamplerAllocation(sampler);
2257
2258 Sampler *samplerObject = getSampler(sampler);
2259 ASSERT(samplerObject);
2260
2261 switch (pname)
2262 {
Jamie Madill9675b802013-07-19 16:36:59 -04002263 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
2264 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
2265 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
2266 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
2267 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002268 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
2269 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
Jamie Madill9675b802013-07-19 16:36:59 -04002270 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround<GLenum>(param)); break;
2271 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround<GLenum>(param)); break;
Jamie Madille29d1672013-07-19 16:36:57 -04002272 default: UNREACHABLE(); break;
2273 }
2274}
2275
Jamie Madill9675b802013-07-19 16:36:59 -04002276GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2277{
2278 mResourceManager->checkSamplerAllocation(sampler);
2279
2280 Sampler *samplerObject = getSampler(sampler);
2281 ASSERT(samplerObject);
2282
2283 switch (pname)
2284 {
2285 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
2286 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
2287 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
2288 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
2289 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
2290 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
2291 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
2292 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getComparisonMode());
2293 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getComparisonFunc());
2294 default: UNREACHABLE(); return 0;
2295 }
2296}
2297
2298GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2299{
2300 mResourceManager->checkSamplerAllocation(sampler);
2301
2302 Sampler *samplerObject = getSampler(sampler);
2303 ASSERT(samplerObject);
2304
2305 switch (pname)
2306 {
2307 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
2308 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
2309 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
2310 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
2311 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
2312 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
2313 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
2314 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getComparisonMode());
2315 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getComparisonFunc());
2316 default: UNREACHABLE(); return 0;
2317 }
2318}
2319
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002320void Context::initRendererString()
2321{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002322 std::ostringstream rendererString;
2323 rendererString << "ANGLE (";
2324 rendererString << mRenderer->getRendererDescription();
2325 rendererString << ")";
2326
Geoff Langcec35902014-04-16 10:52:36 -04002327 mRendererString = MakeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002328}
2329
Geoff Langc0b9ef42014-07-02 10:02:37 -04002330const std::string &Context::getRendererString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002331{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00002332 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002333}
2334
Geoff Langcec35902014-04-16 10:52:36 -04002335void Context::initExtensionStrings()
2336{
Geoff Langc0b9ef42014-07-02 10:02:37 -04002337 mExtensionStrings = mExtensions.getStrings(mClientVersion);
Geoff Langcec35902014-04-16 10:52:36 -04002338
Geoff Langc0b9ef42014-07-02 10:02:37 -04002339 std::ostringstream combinedStringStream;
2340 std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2341 mExtensionString = combinedStringStream.str();
Geoff Langcec35902014-04-16 10:52:36 -04002342}
2343
Geoff Langc0b9ef42014-07-02 10:02:37 -04002344const std::string &Context::getExtensionString() const
Geoff Langcec35902014-04-16 10:52:36 -04002345{
2346 return mExtensionString;
2347}
2348
Geoff Langc0b9ef42014-07-02 10:02:37 -04002349const std::string &Context::getExtensionString(size_t idx) const
Geoff Langcec35902014-04-16 10:52:36 -04002350{
2351 return mExtensionStrings[idx];
2352}
2353
2354size_t Context::getExtensionStringCount() const
2355{
2356 return mExtensionStrings.size();
2357}
2358
Geoff Lang43b00422014-05-12 16:28:07 -04002359size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
Geoff Langcdf22f92013-10-31 10:38:23 -04002360{
Geoff Lang43b00422014-05-12 16:28:07 -04002361 size_t serialCount = 0;
Geoff Langcdf22f92013-10-31 10:38:23 -04002362
Shannon Woods53a94a82014-06-24 15:20:36 -04002363 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
Geoff Langcdf22f92013-10-31 10:38:23 -04002364 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
2365 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002366 FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
2367 if (attachment && attachment->isTexture())
Geoff Langcdf22f92013-10-31 10:38:23 -04002368 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002369 (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
Geoff Langcdf22f92013-10-31 10:38:23 -04002370 }
2371 }
2372
Jamie Madill3c7fa222014-06-05 13:08:51 -04002373 FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
2374 if (depthStencilAttachment && depthStencilAttachment->isTexture())
Geoff Langcdf22f92013-10-31 10:38:23 -04002375 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002376 (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
Geoff Langcdf22f92013-10-31 10:38:23 -04002377 }
2378
Geoff Lang43b00422014-05-12 16:28:07 -04002379 std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
2380
2381 return serialCount;
Geoff Langcdf22f92013-10-31 10:38:23 -04002382}
2383
Geoff Lang758d5b22013-06-11 11:42:50 -04002384void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2385 GLbitfield mask, GLenum filter)
2386{
Shannon Woods53a94a82014-06-24 15:20:36 -04002387 Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2388 Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
Geoff Lang758d5b22013-06-11 11:42:50 -04002389
2390 bool blitRenderTarget = false;
Geoff Lang685806d2013-06-12 11:16:36 -04002391 bool blitDepth = false;
2392 bool blitStencil = false;
Geoff Lang758d5b22013-06-11 11:42:50 -04002393 if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002394 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002395 blitRenderTarget = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04002396 }
2397 if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2398 {
Geoff Lang685806d2013-06-12 11:16:36 -04002399 blitStencil = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04002400 }
2401 if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2402 {
Geoff Lang685806d2013-06-12 11:16:36 -04002403 blitDepth = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002404 }
2405
Geoff Lang125deab2013-08-09 13:34:16 -04002406 gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2407 gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
Geoff Lang685806d2013-06-12 11:16:36 -04002408 if (blitRenderTarget || blitDepth || blitStencil)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002409 {
Shannon Woods53a94a82014-06-24 15:20:36 -04002410 const gl::Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
Geoff Lang125deab2013-08-09 13:34:16 -04002411 mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
Geoff Lang685806d2013-06-12 11:16:36 -04002412 blitRenderTarget, blitDepth, blitStencil, filter);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002413 }
2414}
2415
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002416void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
2417 GLint x, GLint y, GLsizei width, GLsizei height)
2418{
2419 Framebuffer *frameBuffer = NULL;
2420 switch (target)
2421 {
2422 case GL_FRAMEBUFFER:
2423 case GL_DRAW_FRAMEBUFFER:
Shannon Woods53a94a82014-06-24 15:20:36 -04002424 frameBuffer = mState.getDrawFramebuffer();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002425 break;
2426 case GL_READ_FRAMEBUFFER:
Shannon Woods53a94a82014-06-24 15:20:36 -04002427 frameBuffer = mState.getReadFramebuffer();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002428 break;
2429 default:
2430 UNREACHABLE();
2431 }
2432
2433 if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
2434 {
2435 for (int i = 0; i < numAttachments; ++i)
2436 {
2437 rx::RenderTarget *renderTarget = NULL;
2438
2439 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
2440 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002441 gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
2442 if (attachment)
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002443 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002444 renderTarget = attachment->getRenderTarget();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002445 }
2446 }
2447 else if (attachments[i] == GL_COLOR)
2448 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002449 gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
2450 if (attachment)
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002451 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002452 renderTarget = attachment->getRenderTarget();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002453 }
2454 }
2455 else
2456 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002457 gl::FramebufferAttachment *attachment = NULL;
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002458 switch (attachments[i])
2459 {
2460 case GL_DEPTH_ATTACHMENT:
2461 case GL_DEPTH:
Jamie Madill3c7fa222014-06-05 13:08:51 -04002462 attachment = frameBuffer->getDepthbuffer();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002463 break;
2464 case GL_STENCIL_ATTACHMENT:
2465 case GL_STENCIL:
Jamie Madill3c7fa222014-06-05 13:08:51 -04002466 attachment = frameBuffer->getStencilbuffer();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002467 break;
2468 case GL_DEPTH_STENCIL_ATTACHMENT:
Jamie Madill3c7fa222014-06-05 13:08:51 -04002469 attachment = frameBuffer->getDepthOrStencilbuffer();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002470 break;
2471 default:
2472 UNREACHABLE();
2473 }
2474
Jamie Madill3c7fa222014-06-05 13:08:51 -04002475 if (attachment)
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002476 {
Jamie Madill3c7fa222014-06-05 13:08:51 -04002477 renderTarget = attachment->getDepthStencil();
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00002478 }
2479 }
2480
2481 if (renderTarget)
2482 {
2483 renderTarget->invalidate(x, y, width, height);
2484 }
2485 }
2486 }
2487}
2488
Jamie Madill7a5f7382014-03-05 15:01:24 -05002489bool Context::hasMappedBuffer(GLenum target) const
2490{
2491 if (target == GL_ARRAY_BUFFER)
2492 {
2493 for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
2494 {
Shannon Woods53a94a82014-06-24 15:20:36 -04002495 const gl::VertexAttribute &vertexAttrib = mState.getVertexAttribState(attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -07002496 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
Brandon Jonesd38f9262014-06-18 16:26:45 -07002497 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
Jamie Madill7a5f7382014-03-05 15:01:24 -05002498 {
2499 return true;
2500 }
2501 }
2502 }
2503 else if (target == GL_ELEMENT_ARRAY_BUFFER)
2504 {
Shannon Woods53a94a82014-06-24 15:20:36 -04002505 Buffer *elementBuffer = mState.getTargetBuffer(target);
Brandon Jonesd38f9262014-06-18 16:26:45 -07002506 return (elementBuffer && elementBuffer->isMapped());
Jamie Madill7a5f7382014-03-05 15:01:24 -05002507 }
2508 else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
2509 {
2510 UNIMPLEMENTED();
2511 }
2512 else UNREACHABLE();
2513 return false;
2514}
2515
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002516}
2517
2518extern "C"
2519{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00002520gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002521{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00002522 return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002523}
2524
2525void glDestroyContext(gl::Context *context)
2526{
2527 delete context;
2528
2529 if (context == gl::getContext())
2530 {
2531 gl::makeCurrent(NULL, NULL, NULL);
2532 }
2533}
2534
2535void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
2536{
2537 gl::makeCurrent(context, display, surface);
2538}
2539
2540gl::Context *glGetCurrentContext()
2541{
2542 return gl::getContext();
2543}
daniel@transgaming.com621ce052012-10-31 17:52:29 +00002544
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002545}