1//
2// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Context.cpp: Implements the gl::Context class, managing all GL state and performing
8// rendering operations. It is the GLES2 specific implementation of EGLContext.
9
10#include "libGLESv2/Context.h"
11
12#include "libGLESv2/main.h"
13#include "common/utilities.h"
14#include "common/platform.h"
15#include "libGLESv2/formatutils.h"
16#include "libGLESv2/Buffer.h"
17#include "libGLESv2/Fence.h"
18#include "libGLESv2/Framebuffer.h"
19#include "libGLESv2/FramebufferAttachment.h"
20#include "libGLESv2/Renderbuffer.h"
21#include "libGLESv2/Program.h"
22#include "libGLESv2/ProgramBinary.h"
23#include "libGLESv2/Query.h"
24#include "libGLESv2/Texture.h"
25#include "libGLESv2/ResourceManager.h"
26#include "libGLESv2/renderer/d3d/IndexDataManager.h"
27#include "libGLESv2/renderer/Renderer.h"
28#include "libGLESv2/VertexArray.h"
29#include "libGLESv2/Sampler.h"
30#include "libGLESv2/validationES.h"
31#include "libGLESv2/TransformFeedback.h"
32
33#include "libEGL/Surface.h"
34
35#include <sstream>
36
37namespace gl
38{
39
40Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
41    : mRenderer(renderer)
42{
43    ASSERT(robustAccess == false);   // Unimplemented
44
45    initCaps(clientVersion);
46    mState.initialize(mCaps, clientVersion);
47
48    mClientVersion = clientVersion;
49
50    mFenceNVHandleAllocator.setBaseHandle(0);
51
52    if (shareContext != NULL)
53    {
54        mResourceManager = shareContext->mResourceManager;
55        mResourceManager->addRef();
56    }
57    else
58    {
59        mResourceManager = new ResourceManager(mRenderer);
60    }
61
62    // [OpenGL ES 2.0.24] section 3.7 page 83:
63    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
64    // and cube map texture state vectors respectively associated with them.
65    // In order that access to these initial textures not be lost, they are treated as texture
66    // objects all of whose names are 0.
67
68    mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
69    bindTexture(GL_TEXTURE_2D, 0);
70
71    mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
72    bindTexture(GL_TEXTURE_CUBE_MAP, 0);
73
74    if (mClientVersion >= 3)
75    {
76        // TODO: These could also be enabled via extension
77        mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
78        bindTexture(GL_TEXTURE_3D, 0);
79
80        mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
81        bindTexture(GL_TEXTURE_2D_ARRAY, 0);
82    }
83
84    bindVertexArray(0);
85    bindArrayBuffer(0);
86    bindElementArrayBuffer(0);
87
88    bindReadFramebuffer(0);
89    bindDrawFramebuffer(0);
90    bindRenderbuffer(0);
91
92    bindGenericUniformBuffer(0);
93    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
94    {
95        bindIndexedUniformBuffer(0, i, 0, -1);
96    }
97
98    bindGenericTransformFeedbackBuffer(0);
99    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
100    {
101        bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
102    }
103
104    bindCopyReadBuffer(0);
105    bindCopyWriteBuffer(0);
106    bindPixelPackBuffer(0);
107    bindPixelUnpackBuffer(0);
108
109    // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
110    // In the initial state, a default transform feedback object is bound and treated as
111    // a transform feedback object with a name of zero. That object is bound any time
112    // BindTransformFeedback is called with id of zero
113    mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0));
114    bindTransformFeedback(0);
115
116    mHasBeenCurrent = false;
117    mContextLost = false;
118    mResetStatus = GL_NO_ERROR;
119    mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
120    mRobustAccess = robustAccess;
121
122    mState.setContext(this);
123}
124
125Context::~Context()
126{
127    GLuint currentProgram = mState.getCurrentProgramId();
128    if (currentProgram != 0)
129    {
130        Program *programObject = mResourceManager->getProgram(currentProgram);
131        if (programObject)
132        {
133            programObject->release();
134        }
135        currentProgram = 0;
136    }
137    mState.setCurrentProgram(0, NULL);
138
139    while (!mFramebufferMap.empty())
140    {
141        deleteFramebuffer(mFramebufferMap.begin()->first);
142    }
143
144    while (!mFenceNVMap.empty())
145    {
146        deleteFenceNV(mFenceNVMap.begin()->first);
147    }
148
149    while (!mQueryMap.empty())
150    {
151        deleteQuery(mQueryMap.begin()->first);
152    }
153
154    while (!mVertexArrayMap.empty())
155    {
156        deleteVertexArray(mVertexArrayMap.begin()->first);
157    }
158
159    mTransformFeedbackZero.set(NULL);
160    while (!mTransformFeedbackMap.empty())
161    {
162        deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
163    }
164
165    for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
166    {
167        i->second.set(NULL);
168    }
169    mIncompleteTextures.clear();
170
171    for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
172    {
173        i->second.set(NULL);
174    }
175    mZeroTextures.clear();
176
177    mResourceManager->release();
178}
179
180void Context::makeCurrent(egl::Surface *surface)
181{
182    if (!mHasBeenCurrent)
183    {
184        initRendererString();
185        initExtensionStrings();
186
187        mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight());
188        mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight());
189
190        mHasBeenCurrent = true;
191    }
192
193    // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
194    rx::SwapChain *swapchain = surface->getSwapChain();
195
196    Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
197    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
198    Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
199
200    setFramebufferZero(framebufferZero);
201
202    // Store the current client version in the renderer
203    mRenderer->setCurrentClientVersion(mClientVersion);
204}
205
206// NOTE: this function should not assume that this context is current!
207void Context::markContextLost()
208{
209    if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
210        mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
211    mContextLost = true;
212}
213
214bool Context::isContextLost()
215{
216    return mContextLost;
217}
218
219GLuint Context::createBuffer()
220{
221    return mResourceManager->createBuffer();
222}
223
224GLuint Context::createProgram()
225{
226    return mResourceManager->createProgram();
227}
228
229GLuint Context::createShader(GLenum type)
230{
231    return mResourceManager->createShader(type);
232}
233
234GLuint Context::createTexture()
235{
236    return mResourceManager->createTexture();
237}
238
239GLuint Context::createRenderbuffer()
240{
241    return mResourceManager->createRenderbuffer();
242}
243
244GLsync Context::createFenceSync(GLenum condition)
245{
246    GLuint handle = mResourceManager->createFenceSync();
247
248    gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
249    ASSERT(fenceSync);
250
251    fenceSync->set(condition);
252
253    return reinterpret_cast<GLsync>(handle);
254}
255
256GLuint Context::createVertexArray()
257{
258    GLuint handle = mVertexArrayHandleAllocator.allocate();
259
260    // Although the spec states VAO state is not initialized until the object is bound,
261    // we create it immediately. The resulting behaviour is transparent to the application,
262    // since it's not currently possible to access the state until the object is bound.
263    VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
264    mVertexArrayMap[handle] = vertexArray;
265    return handle;
266}
267
268GLuint Context::createSampler()
269{
270    return mResourceManager->createSampler();
271}
272
273GLuint Context::createTransformFeedback()
274{
275    GLuint handle = mTransformFeedbackAllocator.allocate();
276    TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle);
277    transformFeedback->addRef();
278    mTransformFeedbackMap[handle] = transformFeedback;
279    return handle;
280}
281
282// Returns an unused framebuffer name
283GLuint Context::createFramebuffer()
284{
285    GLuint handle = mFramebufferHandleAllocator.allocate();
286
287    mFramebufferMap[handle] = NULL;
288
289    return handle;
290}
291
292GLuint Context::createFenceNV()
293{
294    GLuint handle = mFenceNVHandleAllocator.allocate();
295
296    mFenceNVMap[handle] = new FenceNV(mRenderer);
297
298    return handle;
299}
300
301// Returns an unused query name
302GLuint Context::createQuery()
303{
304    GLuint handle = mQueryHandleAllocator.allocate();
305
306    mQueryMap[handle] = NULL;
307
308    return handle;
309}
310
311void Context::deleteBuffer(GLuint buffer)
312{
313    if (mResourceManager->getBuffer(buffer))
314    {
315        detachBuffer(buffer);
316    }
317
318    mResourceManager->deleteBuffer(buffer);
319}
320
321void Context::deleteShader(GLuint shader)
322{
323    mResourceManager->deleteShader(shader);
324}
325
326void Context::deleteProgram(GLuint program)
327{
328    mResourceManager->deleteProgram(program);
329}
330
331void Context::deleteTexture(GLuint texture)
332{
333    if (mResourceManager->getTexture(texture))
334    {
335        detachTexture(texture);
336    }
337
338    mResourceManager->deleteTexture(texture);
339}
340
341void Context::deleteRenderbuffer(GLuint renderbuffer)
342{
343    if (mResourceManager->getRenderbuffer(renderbuffer))
344    {
345        detachRenderbuffer(renderbuffer);
346    }
347
348    mResourceManager->deleteRenderbuffer(renderbuffer);
349}
350
351void Context::deleteFenceSync(GLsync fenceSync)
352{
353    // The spec specifies the underlying Fence object is not deleted until all current
354    // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
355    // and since our API is currently designed for being called from a single thread, we can delete
356    // the fence immediately.
357    mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
358}
359
360void Context::deleteVertexArray(GLuint vertexArray)
361{
362    auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
363
364    if (vertexArrayObject != mVertexArrayMap.end())
365    {
366        detachVertexArray(vertexArray);
367
368        mVertexArrayHandleAllocator.release(vertexArrayObject->first);
369        delete vertexArrayObject->second;
370        mVertexArrayMap.erase(vertexArrayObject);
371    }
372}
373
374void Context::deleteSampler(GLuint sampler)
375{
376    if (mResourceManager->getSampler(sampler))
377    {
378        detachSampler(sampler);
379    }
380
381    mResourceManager->deleteSampler(sampler);
382}
383
384void Context::deleteTransformFeedback(GLuint transformFeedback)
385{
386    TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
387    if (iter != mTransformFeedbackMap.end())
388    {
389        detachTransformFeedback(transformFeedback);
390        mTransformFeedbackAllocator.release(transformFeedback);
391        iter->second->release();
392        mTransformFeedbackMap.erase(iter);
393    }
394}
395
396void Context::deleteFramebuffer(GLuint framebuffer)
397{
398    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
399
400    if (framebufferObject != mFramebufferMap.end())
401    {
402        detachFramebuffer(framebuffer);
403
404        mFramebufferHandleAllocator.release(framebufferObject->first);
405        delete framebufferObject->second;
406        mFramebufferMap.erase(framebufferObject);
407    }
408}
409
410void Context::deleteFenceNV(GLuint fence)
411{
412    FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
413
414    if (fenceObject != mFenceNVMap.end())
415    {
416        mFenceNVHandleAllocator.release(fenceObject->first);
417        delete fenceObject->second;
418        mFenceNVMap.erase(fenceObject);
419    }
420}
421
422void Context::deleteQuery(GLuint query)
423{
424    QueryMap::iterator queryObject = mQueryMap.find(query);
425    if (queryObject != mQueryMap.end())
426    {
427        mQueryHandleAllocator.release(queryObject->first);
428        if (queryObject->second)
429        {
430            queryObject->second->release();
431        }
432        mQueryMap.erase(queryObject);
433    }
434}
435
436Buffer *Context::getBuffer(GLuint handle)
437{
438    return mResourceManager->getBuffer(handle);
439}
440
441Shader *Context::getShader(GLuint handle) const
442{
443    return mResourceManager->getShader(handle);
444}
445
446Program *Context::getProgram(GLuint handle) const
447{
448    return mResourceManager->getProgram(handle);
449}
450
451Texture *Context::getTexture(GLuint handle) const
452{
453    return mResourceManager->getTexture(handle);
454}
455
456Renderbuffer *Context::getRenderbuffer(GLuint handle)
457{
458    return mResourceManager->getRenderbuffer(handle);
459}
460
461FenceSync *Context::getFenceSync(GLsync handle) const
462{
463    return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
464}
465
466VertexArray *Context::getVertexArray(GLuint handle) const
467{
468    auto vertexArray = mVertexArrayMap.find(handle);
469
470    if (vertexArray == mVertexArrayMap.end())
471    {
472        return NULL;
473    }
474    else
475    {
476        return vertexArray->second;
477    }
478}
479
480Sampler *Context::getSampler(GLuint handle) const
481{
482    return mResourceManager->getSampler(handle);
483}
484
485TransformFeedback *Context::getTransformFeedback(GLuint handle) const
486{
487    if (handle == 0)
488    {
489        return mTransformFeedbackZero.get();
490    }
491    else
492    {
493        TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
494        return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
495    }
496}
497
498bool Context::isSampler(GLuint samplerName) const
499{
500    return mResourceManager->isSampler(samplerName);
501}
502
503void Context::bindArrayBuffer(unsigned int buffer)
504{
505    mResourceManager->checkBufferAllocation(buffer);
506
507    mState.setArrayBufferBinding(getBuffer(buffer));
508}
509
510void Context::bindElementArrayBuffer(unsigned int buffer)
511{
512    mResourceManager->checkBufferAllocation(buffer);
513
514    mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
515}
516
517void Context::bindTexture(GLenum target, GLuint texture)
518{
519    mResourceManager->checkTextureAllocation(texture, target);
520
521    mState.setSamplerTexture(target, getTexture(texture));
522}
523
524void Context::bindReadFramebuffer(GLuint framebuffer)
525{
526    if (!getFramebuffer(framebuffer))
527    {
528        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
529    }
530
531    mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
532}
533
534void Context::bindDrawFramebuffer(GLuint framebuffer)
535{
536    if (!getFramebuffer(framebuffer))
537    {
538        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
539    }
540
541    mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
542}
543
544void Context::bindRenderbuffer(GLuint renderbuffer)
545{
546    mResourceManager->checkRenderbufferAllocation(renderbuffer);
547
548    mState.setRenderbufferBinding(getRenderbuffer(renderbuffer));
549}
550
551void Context::bindVertexArray(GLuint vertexArray)
552{
553    if (!getVertexArray(vertexArray))
554    {
555        VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
556        mVertexArrayMap[vertexArray] = vertexArrayObject;
557    }
558
559    mState.setVertexArrayBinding(getVertexArray(vertexArray));
560}
561
562void Context::bindSampler(GLuint textureUnit, GLuint sampler)
563{
564    ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
565    mResourceManager->checkSamplerAllocation(sampler);
566
567    mState.setSamplerBinding(textureUnit, getSampler(sampler));
568}
569
570void Context::bindGenericUniformBuffer(GLuint buffer)
571{
572    mResourceManager->checkBufferAllocation(buffer);
573
574    mState.setGenericUniformBufferBinding(getBuffer(buffer));
575}
576
577void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
578{
579    mResourceManager->checkBufferAllocation(buffer);
580
581    mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size);
582}
583
584void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
585{
586    mResourceManager->checkBufferAllocation(buffer);
587
588    mState.setGenericTransformFeedbackBufferBinding(getBuffer(buffer));
589}
590
591void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
592{
593    mResourceManager->checkBufferAllocation(buffer);
594
595    mState.setIndexedTransformFeedbackBufferBinding(index, getBuffer(buffer), offset, size);
596}
597
598void Context::bindCopyReadBuffer(GLuint buffer)
599{
600    mResourceManager->checkBufferAllocation(buffer);
601
602    mState.setCopyReadBufferBinding(getBuffer(buffer));
603}
604
605void Context::bindCopyWriteBuffer(GLuint buffer)
606{
607    mResourceManager->checkBufferAllocation(buffer);
608
609    mState.setCopyWriteBufferBinding(getBuffer(buffer));
610}
611
612void Context::bindPixelPackBuffer(GLuint buffer)
613{
614    mResourceManager->checkBufferAllocation(buffer);
615
616    mState.setPixelPackBufferBinding(getBuffer(buffer));
617}
618
619void Context::bindPixelUnpackBuffer(GLuint buffer)
620{
621    mResourceManager->checkBufferAllocation(buffer);
622
623    mState.setPixelUnpackBufferBinding(getBuffer(buffer));
624}
625
626void Context::useProgram(GLuint program)
627{
628    GLuint priorProgramId = mState.getCurrentProgramId();
629    Program *priorProgram = mResourceManager->getProgram(priorProgramId);
630
631    if (priorProgramId != program)
632    {
633        mState.setCurrentProgram(program, mResourceManager->getProgram(program));
634
635        if (priorProgram)
636        {
637            priorProgram->release();
638        }
639    }
640}
641
642void Context::linkProgram(GLuint program)
643{
644    Program *programObject = mResourceManager->getProgram(program);
645
646    bool linked = programObject->link(getCaps());
647
648    // if the current program was relinked successfully we
649    // need to install the new executables
650    if (linked && program == mState.getCurrentProgramId())
651    {
652        mState.setCurrentProgramBinary(programObject->getProgramBinary());
653    }
654}
655
656void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
657{
658    Program *programObject = mResourceManager->getProgram(program);
659
660    bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
661
662    // if the current program was reloaded successfully we
663    // need to install the new executables
664    if (loaded && program == mState.getCurrentProgramId())
665    {
666        mState.setCurrentProgramBinary(programObject->getProgramBinary());
667    }
668
669}
670
671void Context::bindTransformFeedback(GLuint transformFeedback)
672{
673    mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
674}
675
676Error Context::beginQuery(GLenum target, GLuint query)
677{
678    Query *queryObject = getQuery(query, true, target);
679    ASSERT(queryObject);
680
681    // begin query
682    Error error = queryObject->begin();
683    if (error.isError())
684    {
685        return error;
686    }
687
688    // set query as active for specified target only if begin succeeded
689    mState.setActiveQuery(target, queryObject);
690
691    return Error(GL_NO_ERROR);
692}
693
694Error Context::endQuery(GLenum target)
695{
696    Query *queryObject = mState.getActiveQuery(target);
697    ASSERT(queryObject);
698
699    gl::Error error = queryObject->end();
700
701    // Always unbind the query, even if there was an error. This may delete the query object.
702    mState.setActiveQuery(target, NULL);
703
704    return error;
705}
706
707void Context::setFramebufferZero(Framebuffer *buffer)
708{
709    // First, check to see if the old default framebuffer
710    // was set for draw or read framebuffer, and change
711    // the bindings to point to the new one before deleting it.
712    if (mState.getDrawFramebuffer()->id() == 0)
713    {
714        mState.setDrawFramebufferBinding(buffer);
715    }
716
717    if (mState.getReadFramebuffer()->id() == 0)
718    {
719        mState.setReadFramebufferBinding(buffer);
720    }
721
722    delete mFramebufferMap[0];
723    mFramebufferMap[0] = buffer;
724}
725
726void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
727{
728    ASSERT(getTextureCaps().get(internalformat).renderable);
729
730    RenderbufferStorage *renderbuffer = NULL;
731
732    const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
733    if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
734    {
735        renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
736    }
737    else if (formatInfo.depthBits > 0)
738    {
739        renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
740    }
741    else if (formatInfo.stencilBits > 0)
742    {
743        renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
744    }
745    else
746    {
747        renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
748    }
749
750    mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
751}
752
753Framebuffer *Context::getFramebuffer(unsigned int handle) const
754{
755    FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
756
757    if (framebuffer == mFramebufferMap.end())
758    {
759        return NULL;
760    }
761    else
762    {
763        return framebuffer->second;
764    }
765}
766
767FenceNV *Context::getFenceNV(unsigned int handle)
768{
769    FenceNVMap::iterator fence = mFenceNVMap.find(handle);
770
771    if (fence == mFenceNVMap.end())
772    {
773        return NULL;
774    }
775    else
776    {
777        return fence->second;
778    }
779}
780
781Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
782{
783    QueryMap::iterator query = mQueryMap.find(handle);
784
785    if (query == mQueryMap.end())
786    {
787        return NULL;
788    }
789    else
790    {
791        if (!query->second && create)
792        {
793            query->second = new Query(mRenderer->createQuery(type), handle);
794            query->second->addRef();
795        }
796        return query->second;
797    }
798}
799
800Texture *Context::getTargetTexture(GLenum target) const
801{
802    if (!ValidTextureTarget(this, target))
803    {
804        return NULL;
805    }
806
807    switch (target)
808    {
809      case GL_TEXTURE_2D:       return getTexture2D();
810      case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
811      case GL_TEXTURE_3D:       return getTexture3D();
812      case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
813      default:                  return NULL;
814    }
815}
816
817Texture2D *Context::getTexture2D() const
818{
819    return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
820}
821
822TextureCubeMap *Context::getTextureCubeMap() const
823{
824    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
825}
826
827Texture3D *Context::getTexture3D() const
828{
829    return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
830}
831
832Texture2DArray *Context::getTexture2DArray() const
833{
834    return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
835}
836
837Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
838{
839    if (mState.getSamplerTextureId(sampler, type) == 0)
840    {
841        return mZeroTextures.at(type).get();
842    }
843    else
844    {
845        return mState.getSamplerTexture(sampler, type);
846    }
847}
848
849void Context::getBooleanv(GLenum pname, GLboolean *params)
850{
851    switch (pname)
852    {
853      case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
854      case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
855      default:
856        mState.getBooleanv(pname, params);
857        break;
858    }
859}
860
861void Context::getFloatv(GLenum pname, GLfloat *params)
862{
863    // Queries about context capabilities and maximums are answered by Context.
864    // Queries about current GL state values are answered by State.
865    switch (pname)
866    {
867      case GL_ALIASED_LINE_WIDTH_RANGE:
868        params[0] = mCaps.minAliasedLineWidth;
869        params[1] = mCaps.maxAliasedLineWidth;
870        break;
871      case GL_ALIASED_POINT_SIZE_RANGE:
872        params[0] = mCaps.minAliasedPointSize;
873        params[1] = mCaps.maxAliasedPointSize;
874        break;
875      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
876        ASSERT(mExtensions.textureFilterAnisotropic);
877        *params = mExtensions.maxTextureAnisotropy;
878        break;
879      default:
880        mState.getFloatv(pname, params);
881        break;
882    }
883}
884
885void Context::getIntegerv(GLenum pname, GLint *params)
886{
887    // Queries about context capabilities and maximums are answered by Context.
888    // Queries about current GL state values are answered by State.
889
890    switch (pname)
891    {
892      case GL_MAX_VERTEX_ATTRIBS:                       *params = mCaps.maxVertexAttributes;                            break;
893      case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mCaps.maxVertexUniformVectors;                        break;
894      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mCaps.maxVertexUniformComponents;                     break;
895      case GL_MAX_VARYING_VECTORS:                      *params = mCaps.maxVaryingVectors;                              break;
896      case GL_MAX_VARYING_COMPONENTS:                   *params = mCaps.maxVertexOutputComponents;                      break;
897      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mCaps.maxCombinedTextureImageUnits;                   break;
898      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mCaps.maxVertexTextureImageUnits;                     break;
899      case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = mCaps.maxTextureImageUnits;                           break;
900      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mCaps.maxFragmentUniformVectors;                      break;
901      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mCaps.maxFragmentInputComponents;                     break;
902      case GL_MAX_RENDERBUFFER_SIZE:                    *params = mCaps.maxRenderbufferSize;                            break;
903      case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mCaps.maxColorAttachments;                            break;
904      case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mCaps.maxDrawBuffers;                                 break;
905      //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
906      case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
907      case GL_MAX_TEXTURE_SIZE:                         *params = mCaps.max2DTextureSize;                               break;
908      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = mCaps.maxCubeMapTextureSize;                          break;
909      case GL_MAX_3D_TEXTURE_SIZE:                      *params = mCaps.max3DTextureSize;                               break;
910      case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = mCaps.maxArrayTextureLayers;                          break;
911      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = mCaps.uniformBufferOffsetAlignment;                   break;
912      case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = mCaps.maxUniformBufferBindings;                       break;
913      case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mCaps.maxVertexUniformBlocks;                         break;
914      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mCaps.maxFragmentUniformBlocks;                       break;
915      case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = mCaps.maxCombinedTextureImageUnits;                   break;
916      case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
917      case GL_MINOR_VERSION:                            *params = 0;                                                    break;
918      case GL_MAX_ELEMENTS_INDICES:                     *params = mCaps.maxElementsIndices;                             break;
919      case GL_MAX_ELEMENTS_VERTICES:                    *params = mCaps.maxElementsVertices;                            break;
920      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
921      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mCaps.maxTransformFeedbackSeparateAttributes;    break;
922      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mCaps.maxTransformFeedbackSeparateComponents;    break;
923      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:           *params = mCaps.compressedTextureFormats.size();                break;
924      case GL_MAX_SAMPLES_ANGLE:                        *params = mExtensions.maxSamples;                               break;
925      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
926      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
927        {
928            GLenum internalFormat, format, type;
929            getCurrentReadFormatType(&internalFormat, &format, &type);
930            if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
931                *params = format;
932            else
933                *params = type;
934        }
935        break;
936      case GL_MAX_VIEWPORT_DIMS:
937        {
938            params[0] = mCaps.maxViewportWidth;
939            params[1] = mCaps.maxViewportHeight;
940        }
941        break;
942      case GL_COMPRESSED_TEXTURE_FORMATS:
943        std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
944        break;
945      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
946        *params = mResetStrategy;
947        break;
948      case GL_NUM_SHADER_BINARY_FORMATS:
949        *params = mCaps.shaderBinaryFormats.size();
950        break;
951      case GL_SHADER_BINARY_FORMATS:
952        std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
953        break;
954      case GL_NUM_PROGRAM_BINARY_FORMATS:
955        *params = mCaps.programBinaryFormats.size();
956        break;
957      case GL_PROGRAM_BINARY_FORMATS:
958        std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
959        break;
960      case GL_NUM_EXTENSIONS:
961        *params = static_cast<GLint>(mExtensionStrings.size());
962        break;
963      default:
964        mState.getIntegerv(pname, params);
965        break;
966    }
967}
968
969void Context::getInteger64v(GLenum pname, GLint64 *params)
970{
971    // Queries about context capabilities and maximums are answered by Context.
972    // Queries about current GL state values are answered by State.
973    switch (pname)
974    {
975      case GL_MAX_ELEMENT_INDEX:
976        *params = mCaps.maxElementIndex;
977        break;
978      case GL_MAX_UNIFORM_BLOCK_SIZE:
979        *params = mCaps.maxUniformBlockSize;
980        break;
981      case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
982        *params = mCaps.maxCombinedVertexUniformComponents;
983        break;
984      case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
985        *params = mCaps.maxCombinedFragmentUniformComponents;
986        break;
987      case GL_MAX_SERVER_WAIT_TIMEOUT:
988        *params = mCaps.maxServerWaitTimeout;
989        break;
990      default:
991        UNREACHABLE();
992        break;
993    }
994}
995
996bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
997{
998    // Queries about context capabilities and maximums are answered by Context.
999    // Queries about current GL state values are answered by State.
1000    // Indexed integer queries all refer to current state, so this function is a
1001    // mere passthrough.
1002    return mState.getIndexedIntegerv(target, index, data);
1003}
1004
1005bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1006{
1007    // Queries about context capabilities and maximums are answered by Context.
1008    // Queries about current GL state values are answered by State.
1009    // Indexed integer queries all refer to current state, so this function is a
1010    // mere passthrough.
1011    return mState.getIndexedInteger64v(target, index, data);
1012}
1013
1014bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1015{
1016    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1017    {
1018        *type = GL_INT;
1019        *numParams = 1;
1020        return true;
1021    }
1022
1023    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1024    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1025    // to the fact that it is stored internally as a float, and so would require conversion
1026    // if returned from Context::getIntegerv. Since this conversion is already implemented
1027    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1028    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1029    // application.
1030    switch (pname)
1031    {
1032      case GL_COMPRESSED_TEXTURE_FORMATS:
1033        {
1034            *type = GL_INT;
1035            *numParams = mCaps.compressedTextureFormats.size();
1036        }
1037        return true;
1038      case GL_PROGRAM_BINARY_FORMATS_OES:
1039        {
1040            *type = GL_INT;
1041            *numParams = mCaps.programBinaryFormats.size();
1042        }
1043        return true;
1044      case GL_SHADER_BINARY_FORMATS:
1045        {
1046            *type = GL_INT;
1047            *numParams = mCaps.shaderBinaryFormats.size();
1048        }
1049        return true;
1050      case GL_MAX_VERTEX_ATTRIBS:
1051      case GL_MAX_VERTEX_UNIFORM_VECTORS:
1052      case GL_MAX_VARYING_VECTORS:
1053      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1054      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1055      case GL_MAX_TEXTURE_IMAGE_UNITS:
1056      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1057      case GL_MAX_RENDERBUFFER_SIZE:
1058      case GL_MAX_COLOR_ATTACHMENTS_EXT:
1059      case GL_MAX_DRAW_BUFFERS_EXT:
1060      case GL_NUM_SHADER_BINARY_FORMATS:
1061      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1062      case GL_ARRAY_BUFFER_BINDING:
1063      //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
1064      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
1065      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
1066      case GL_RENDERBUFFER_BINDING:
1067      case GL_CURRENT_PROGRAM:
1068      case GL_PACK_ALIGNMENT:
1069      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1070      case GL_UNPACK_ALIGNMENT:
1071      case GL_GENERATE_MIPMAP_HINT:
1072      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1073      case GL_RED_BITS:
1074      case GL_GREEN_BITS:
1075      case GL_BLUE_BITS:
1076      case GL_ALPHA_BITS:
1077      case GL_DEPTH_BITS:
1078      case GL_STENCIL_BITS:
1079      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1080      case GL_CULL_FACE_MODE:
1081      case GL_FRONT_FACE:
1082      case GL_ACTIVE_TEXTURE:
1083      case GL_STENCIL_FUNC:
1084      case GL_STENCIL_VALUE_MASK:
1085      case GL_STENCIL_REF:
1086      case GL_STENCIL_FAIL:
1087      case GL_STENCIL_PASS_DEPTH_FAIL:
1088      case GL_STENCIL_PASS_DEPTH_PASS:
1089      case GL_STENCIL_BACK_FUNC:
1090      case GL_STENCIL_BACK_VALUE_MASK:
1091      case GL_STENCIL_BACK_REF:
1092      case GL_STENCIL_BACK_FAIL:
1093      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1094      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1095      case GL_DEPTH_FUNC:
1096      case GL_BLEND_SRC_RGB:
1097      case GL_BLEND_SRC_ALPHA:
1098      case GL_BLEND_DST_RGB:
1099      case GL_BLEND_DST_ALPHA:
1100      case GL_BLEND_EQUATION_RGB:
1101      case GL_BLEND_EQUATION_ALPHA:
1102      case GL_STENCIL_WRITEMASK:
1103      case GL_STENCIL_BACK_WRITEMASK:
1104      case GL_STENCIL_CLEAR_VALUE:
1105      case GL_SUBPIXEL_BITS:
1106      case GL_MAX_TEXTURE_SIZE:
1107      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1108      case GL_SAMPLE_BUFFERS:
1109      case GL_SAMPLES:
1110      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1111      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1112      case GL_TEXTURE_BINDING_2D:
1113      case GL_TEXTURE_BINDING_CUBE_MAP:
1114      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1115      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1116        {
1117            *type = GL_INT;
1118            *numParams = 1;
1119        }
1120        return true;
1121      case GL_MAX_SAMPLES_ANGLE:
1122        {
1123            if (mExtensions.framebufferMultisample)
1124            {
1125                *type = GL_INT;
1126                *numParams = 1;
1127            }
1128            else
1129            {
1130                return false;
1131            }
1132        }
1133        return true;
1134      case GL_PIXEL_PACK_BUFFER_BINDING:
1135      case GL_PIXEL_UNPACK_BUFFER_BINDING:
1136        {
1137            if (mExtensions.pixelBufferObject)
1138            {
1139                *type = GL_INT;
1140                *numParams = 1;
1141            }
1142            else
1143            {
1144                return false;
1145            }
1146        }
1147        return true;
1148      case GL_MAX_VIEWPORT_DIMS:
1149        {
1150            *type = GL_INT;
1151            *numParams = 2;
1152        }
1153        return true;
1154      case GL_VIEWPORT:
1155      case GL_SCISSOR_BOX:
1156        {
1157            *type = GL_INT;
1158            *numParams = 4;
1159        }
1160        return true;
1161      case GL_SHADER_COMPILER:
1162      case GL_SAMPLE_COVERAGE_INVERT:
1163      case GL_DEPTH_WRITEMASK:
1164      case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1165      case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1166      case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1167      case GL_SAMPLE_COVERAGE:
1168      case GL_SCISSOR_TEST:
1169      case GL_STENCIL_TEST:
1170      case GL_DEPTH_TEST:
1171      case GL_BLEND:
1172      case GL_DITHER:
1173      case GL_CONTEXT_ROBUST_ACCESS_EXT:
1174        {
1175            *type = GL_BOOL;
1176            *numParams = 1;
1177        }
1178        return true;
1179      case GL_COLOR_WRITEMASK:
1180        {
1181            *type = GL_BOOL;
1182            *numParams = 4;
1183        }
1184        return true;
1185      case GL_POLYGON_OFFSET_FACTOR:
1186      case GL_POLYGON_OFFSET_UNITS:
1187      case GL_SAMPLE_COVERAGE_VALUE:
1188      case GL_DEPTH_CLEAR_VALUE:
1189      case GL_LINE_WIDTH:
1190        {
1191            *type = GL_FLOAT;
1192            *numParams = 1;
1193        }
1194        return true;
1195      case GL_ALIASED_LINE_WIDTH_RANGE:
1196      case GL_ALIASED_POINT_SIZE_RANGE:
1197      case GL_DEPTH_RANGE:
1198        {
1199            *type = GL_FLOAT;
1200            *numParams = 2;
1201        }
1202        return true;
1203      case GL_COLOR_CLEAR_VALUE:
1204      case GL_BLEND_COLOR:
1205        {
1206            *type = GL_FLOAT;
1207            *numParams = 4;
1208        }
1209        return true;
1210      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1211        if (!mExtensions.maxTextureAnisotropy)
1212        {
1213            return false;
1214        }
1215        *type = GL_FLOAT;
1216        *numParams = 1;
1217        return true;
1218    }
1219
1220    if (mClientVersion < 3)
1221    {
1222        return false;
1223    }
1224
1225    // Check for ES3.0+ parameter names
1226    switch (pname)
1227    {
1228      case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1229      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1230      case GL_UNIFORM_BUFFER_BINDING:
1231      case GL_TRANSFORM_FEEDBACK_BINDING:
1232      case GL_COPY_READ_BUFFER_BINDING:
1233      case GL_COPY_WRITE_BUFFER_BINDING:
1234      case GL_TEXTURE_BINDING_3D:
1235      case GL_TEXTURE_BINDING_2D_ARRAY:
1236      case GL_MAX_3D_TEXTURE_SIZE:
1237      case GL_MAX_ARRAY_TEXTURE_LAYERS:
1238      case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1239      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1240      case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1241      case GL_MAX_VARYING_COMPONENTS:
1242      case GL_VERTEX_ARRAY_BINDING:
1243      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1244      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1245      case GL_NUM_EXTENSIONS:
1246      case GL_MAJOR_VERSION:
1247      case GL_MINOR_VERSION:
1248      case GL_MAX_ELEMENTS_INDICES:
1249      case GL_MAX_ELEMENTS_VERTICES:
1250      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1251      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1252      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1253        {
1254            *type = GL_INT;
1255            *numParams = 1;
1256        }
1257        return true;
1258
1259      case GL_MAX_ELEMENT_INDEX:
1260      case GL_MAX_UNIFORM_BLOCK_SIZE:
1261      case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1262      case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1263      case GL_MAX_SERVER_WAIT_TIMEOUT:
1264        {
1265            *type = GL_INT_64_ANGLEX;
1266            *numParams = 1;
1267        }
1268        return true;
1269
1270      case GL_TRANSFORM_FEEDBACK_ACTIVE:
1271      case GL_TRANSFORM_FEEDBACK_PAUSED:
1272        {
1273            *type = GL_BOOL;
1274            *numParams = 1;
1275        }
1276        return true;
1277    }
1278
1279    return false;
1280}
1281
1282bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
1283{
1284    if (mClientVersion < 3)
1285    {
1286        return false;
1287    }
1288
1289    switch (target)
1290    {
1291      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1292      case GL_UNIFORM_BUFFER_BINDING:
1293        {
1294            *type = GL_INT;
1295            *numParams = 1;
1296        }
1297        return true;
1298      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1299      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1300      case GL_UNIFORM_BUFFER_START:
1301      case GL_UNIFORM_BUFFER_SIZE:
1302        {
1303            *type = GL_INT_64_ANGLEX;
1304            *numParams = 1;
1305        }
1306    }
1307
1308    return false;
1309}
1310
1311// Applies the render target surface, depth stencil surface, viewport rectangle and
1312// scissor rectangle to the renderer
1313void Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
1314{
1315    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
1316    ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
1317
1318    mRenderer->applyRenderTarget(framebufferObject);
1319
1320    float nearZ, farZ;
1321    mState.getDepthRange(&nearZ, &farZ);
1322    mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
1323                           ignoreViewport);
1324
1325    mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
1326}
1327
1328// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
1329void Context::applyState(GLenum drawMode)
1330{
1331    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
1332    int samples = framebufferObject->getSamples();
1333
1334    RasterizerState rasterizer = mState.getRasterizerState();
1335    rasterizer.pointDrawMode = (drawMode == GL_POINTS);
1336    rasterizer.multiSample = (samples != 0);
1337
1338    mRenderer->setRasterizerState(rasterizer);
1339
1340    unsigned int mask = 0;
1341    if (mState.isSampleCoverageEnabled())
1342    {
1343        GLclampf coverageValue;
1344        bool coverageInvert = false;
1345        mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
1346        if (coverageValue != 0)
1347        {
1348
1349            float threshold = 0.5f;
1350
1351            for (int i = 0; i < samples; ++i)
1352            {
1353                mask <<= 1;
1354
1355                if ((i + 1) * coverageValue >= threshold)
1356                {
1357                    threshold += 1.0f;
1358                    mask |= 1;
1359                }
1360            }
1361        }
1362
1363        if (coverageInvert)
1364        {
1365            mask = ~mask;
1366        }
1367    }
1368    else
1369    {
1370        mask = 0xFFFFFFFF;
1371    }
1372    mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
1373
1374    mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
1375                                    rasterizer.frontFace == GL_CCW);
1376}
1377
1378// Applies the shaders and shader constants to the Direct3D 9 device
1379void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
1380{
1381    const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
1382
1383    VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
1384    VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
1385
1386    const Framebuffer *fbo = mState.getDrawFramebuffer();
1387
1388    mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
1389
1390    programBinary->applyUniforms();
1391}
1392
1393void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
1394{
1395    size_t samplerRange = programBinary->getUsedSamplerRange(type);
1396
1397    for (size_t i = 0; i < samplerRange; i++)
1398    {
1399        GLenum textureType = programBinary->getSamplerTextureType(type, i);
1400        GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
1401        if (textureUnit != -1)
1402        {
1403            Texture* texture = getSamplerTexture(textureUnit, textureType);
1404            if (texture->getSamplerState().swizzleRequired())
1405            {
1406                mRenderer->generateSwizzle(texture);
1407            }
1408        }
1409    }
1410}
1411
1412void Context::generateSwizzles(ProgramBinary *programBinary)
1413{
1414    generateSwizzles(programBinary, SAMPLER_VERTEX);
1415    generateSwizzles(programBinary, SAMPLER_PIXEL);
1416}
1417
1418// For each Direct3D sampler of either the pixel or vertex stage,
1419// looks up the corresponding OpenGL texture image unit and texture type,
1420// and sets the texture and its addressing/filtering state (or NULL when inactive).
1421void Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
1422                            const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
1423{
1424    size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
1425    for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
1426    {
1427        GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
1428        GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
1429        if (textureUnit != -1)
1430        {
1431            SamplerState sampler;
1432            Texture* texture = getSamplerTexture(textureUnit, textureType);
1433            texture->getSamplerStateWithNativeOffset(&sampler);
1434
1435            Sampler *samplerObject = mState.getSampler(textureUnit);
1436            if (samplerObject)
1437            {
1438                samplerObject->getState(&sampler);
1439            }
1440
1441            // TODO: std::binary_search may become unavailable using older versions of GCC
1442            if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
1443                !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
1444            {
1445                mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
1446                mRenderer->setTexture(shaderType, samplerIndex, texture);
1447            }
1448            else
1449            {
1450                // Texture is not sampler complete or it is in use by the framebuffer.  Bind the incomplete texture.
1451                Texture *incompleteTexture = getIncompleteTexture(textureType);
1452                mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
1453            }
1454        }
1455        else
1456        {
1457            // No texture bound to this slot even though it is used by the shader, bind a NULL texture
1458            mRenderer->setTexture(shaderType, samplerIndex, NULL);
1459        }
1460    }
1461
1462    // Set all the remaining textures to NULL
1463    size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
1464                                                        : mCaps.maxVertexTextureImageUnits;
1465    for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
1466    {
1467        mRenderer->setTexture(shaderType, samplerIndex, NULL);
1468    }
1469}
1470
1471void Context::applyTextures(ProgramBinary *programBinary)
1472{
1473    FramebufferTextureSerialArray framebufferSerials;
1474    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
1475
1476    applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
1477    applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
1478}
1479
1480bool Context::applyUniformBuffers()
1481{
1482    Program *programObject = getProgram(mState.getCurrentProgramId());
1483    ProgramBinary *programBinary = programObject->getProgramBinary();
1484
1485    std::vector<Buffer*> boundBuffers;
1486
1487    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
1488    {
1489        GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
1490
1491        if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
1492        {
1493            // undefined behaviour
1494            return false;
1495        }
1496        else
1497        {
1498            Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
1499            ASSERT(uniformBuffer);
1500            boundBuffers.push_back(uniformBuffer);
1501        }
1502    }
1503
1504    return programBinary->applyUniformBuffers(boundBuffers, getCaps());
1505}
1506
1507bool Context::applyTransformFeedbackBuffers()
1508{
1509    TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
1510    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
1511    {
1512        Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1513        GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1514        for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1515        {
1516            transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
1517            transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
1518        }
1519        mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
1520        return true;
1521    }
1522    else
1523    {
1524        return false;
1525    }
1526}
1527
1528void Context::markTransformFeedbackUsage()
1529{
1530    for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1531    {
1532        Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
1533        if (buffer)
1534        {
1535            buffer->markTransformFeedbackUsage();
1536        }
1537    }
1538}
1539
1540Error Context::clear(GLbitfield mask)
1541{
1542    if (mState.isRasterizerDiscardEnabled())
1543    {
1544        return Error(GL_NO_ERROR);
1545    }
1546
1547    ClearParameters clearParams = mState.getClearParameters(mask);
1548
1549    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
1550
1551    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
1552}
1553
1554Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
1555{
1556    if (mState.isRasterizerDiscardEnabled())
1557    {
1558        return Error(GL_NO_ERROR);
1559    }
1560
1561    // glClearBufferfv can be called to clear the color buffer or depth buffer
1562    ClearParameters clearParams = mState.getClearParameters(0);
1563
1564    if (buffer == GL_COLOR)
1565    {
1566        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1567        {
1568            clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1569        }
1570        clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
1571        clearParams.colorClearType = GL_FLOAT;
1572    }
1573
1574    if (buffer == GL_DEPTH)
1575    {
1576        clearParams.clearDepth = true;
1577        clearParams.depthClearValue = values[0];
1578    }
1579
1580    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
1581
1582    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
1583}
1584
1585Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
1586{
1587    if (mState.isRasterizerDiscardEnabled())
1588    {
1589        return Error(GL_NO_ERROR);
1590    }
1591
1592    // glClearBufferuv can only be called to clear a color buffer
1593    ClearParameters clearParams = mState.getClearParameters(0);
1594    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1595    {
1596        clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1597    }
1598    clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
1599    clearParams.colorClearType = GL_UNSIGNED_INT;
1600
1601    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
1602
1603    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
1604}
1605
1606Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
1607{
1608    if (mState.isRasterizerDiscardEnabled())
1609    {
1610        return Error(GL_NO_ERROR);
1611    }
1612
1613    // glClearBufferfv can be called to clear the color buffer or stencil buffer
1614    ClearParameters clearParams = mState.getClearParameters(0);
1615
1616    if (buffer == GL_COLOR)
1617    {
1618        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
1619        {
1620            clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
1621        }
1622        clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
1623        clearParams.colorClearType = GL_INT;
1624    }
1625
1626    if (buffer == GL_STENCIL)
1627    {
1628        clearParams.clearStencil = true;
1629        clearParams.stencilClearValue = values[1];
1630    }
1631
1632    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
1633
1634    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
1635}
1636
1637Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
1638{
1639    if (mState.isRasterizerDiscardEnabled())
1640    {
1641        return Error(GL_NO_ERROR);
1642    }
1643
1644    // glClearBufferfi can only be called to clear a depth stencil buffer
1645    ClearParameters clearParams = mState.getClearParameters(0);
1646    clearParams.clearDepth = true;
1647    clearParams.depthClearValue = depth;
1648    clearParams.clearStencil = true;
1649    clearParams.stencilClearValue = stencil;
1650
1651    applyRenderTarget(GL_TRIANGLES, true);   // Clips the clear to the scissor rectangle but not the viewport
1652
1653    return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
1654}
1655
1656Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1657                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
1658{
1659    Framebuffer *framebuffer = mState.getReadFramebuffer();
1660
1661    GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
1662    const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
1663    GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
1664
1665    return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
1666                                 reinterpret_cast<uint8_t*>(pixels));
1667}
1668
1669void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
1670{
1671    ASSERT(mState.getCurrentProgramId() != 0);
1672
1673    ProgramBinary *programBinary = mState.getCurrentProgramBinary();
1674    programBinary->updateSamplerMapping();
1675
1676    generateSwizzles(programBinary);
1677
1678    if (!mRenderer->applyPrimitiveType(mode, count))
1679    {
1680        return;
1681    }
1682
1683    applyRenderTarget(mode, false);
1684    applyState(mode);
1685
1686    Error error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
1687    if (error.isError())
1688    {
1689        return gl::error(error.getCode());
1690    }
1691
1692    bool transformFeedbackActive = applyTransformFeedbackBuffers();
1693
1694    applyShaders(programBinary, transformFeedbackActive);
1695
1696    applyTextures(programBinary);
1697
1698    if (!applyUniformBuffers())
1699    {
1700        return;
1701    }
1702
1703    if (!skipDraw(mode))
1704    {
1705        mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
1706
1707        if (transformFeedbackActive)
1708        {
1709            markTransformFeedbackUsage();
1710        }
1711    }
1712}
1713
1714void Context::drawElements(GLenum mode, GLsizei count, GLenum type,
1715                           const GLvoid *indices, GLsizei instances,
1716                           const rx::RangeUI &indexRange)
1717{
1718    ASSERT(mState.getCurrentProgramId() != 0);
1719
1720    ProgramBinary *programBinary = mState.getCurrentProgramBinary();
1721    programBinary->updateSamplerMapping();
1722
1723    generateSwizzles(programBinary);
1724
1725    if (!mRenderer->applyPrimitiveType(mode, count))
1726    {
1727        return;
1728    }
1729
1730    applyRenderTarget(mode, false);
1731    applyState(mode);
1732
1733    VertexArray *vao = mState.getVertexArray();
1734    rx::TranslatedIndexData indexInfo;
1735    indexInfo.indexRange = indexRange;
1736    Error error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
1737    if (error.isError())
1738    {
1739        return gl::error(error.getCode());
1740    }
1741
1742    GLsizei vertexCount = indexInfo.indexRange.length() + 1;
1743    error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
1744                                         mState.getVertexAttribCurrentValues(),
1745                                         indexInfo.indexRange.start, vertexCount, instances);
1746    if (error.isError())
1747    {
1748        return gl::error(error.getCode());
1749    }
1750
1751    bool transformFeedbackActive = applyTransformFeedbackBuffers();
1752    // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
1753    // layer.
1754    ASSERT(!transformFeedbackActive);
1755
1756    applyShaders(programBinary, transformFeedbackActive);
1757
1758    applyTextures(programBinary);
1759
1760    if (!applyUniformBuffers())
1761    {
1762        return;
1763    }
1764
1765    if (!skipDraw(mode))
1766    {
1767        mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
1768    }
1769}
1770
1771// Implements glFlush when block is false, glFinish when block is true
1772void Context::sync(bool block)
1773{
1774    mRenderer->sync(block);
1775}
1776
1777void Context::recordError(const Error &error)
1778{
1779    if (error.isError())
1780    {
1781        mErrors.insert(error.getCode());
1782    }
1783}
1784
1785// Get one of the recorded errors and clear its flag, if any.
1786// [OpenGL ES 2.0.24] section 2.5 page 13.
1787GLenum Context::getError()
1788{
1789    if (mErrors.empty())
1790    {
1791        return GL_NO_ERROR;
1792    }
1793    else
1794    {
1795        GLenum error = *mErrors.begin();
1796        mErrors.erase(mErrors.begin());
1797        return error;
1798    }
1799}
1800
1801GLenum Context::getResetStatus()
1802{
1803    if (mResetStatus == GL_NO_ERROR && !mContextLost)
1804    {
1805        // mResetStatus will be set by the markContextLost callback
1806        // in the case a notification is sent
1807        mRenderer->testDeviceLost(true);
1808    }
1809
1810    GLenum status = mResetStatus;
1811
1812    if (mResetStatus != GL_NO_ERROR)
1813    {
1814        ASSERT(mContextLost);
1815
1816        if (mRenderer->testDeviceResettable())
1817        {
1818            mResetStatus = GL_NO_ERROR;
1819        }
1820    }
1821
1822    return status;
1823}
1824
1825bool Context::isResetNotificationEnabled()
1826{
1827    return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
1828}
1829
1830int Context::getClientVersion() const
1831{
1832    return mClientVersion;
1833}
1834
1835const Caps &Context::getCaps() const
1836{
1837    return mCaps;
1838}
1839
1840const TextureCapsMap &Context::getTextureCaps() const
1841{
1842    return mTextureCaps;
1843}
1844
1845const Extensions &Context::getExtensions() const
1846{
1847    return mExtensions;
1848}
1849
1850void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
1851{
1852    Framebuffer *framebuffer = mState.getReadFramebuffer();
1853    ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
1854
1855    FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
1856    ASSERT(attachment);
1857
1858    GLenum actualFormat = attachment->getActualFormat();
1859    const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
1860
1861    *internalFormat = actualFormat;
1862    *format = actualFormatInfo.format;
1863    *type = actualFormatInfo.type;
1864}
1865
1866void Context::detachTexture(GLuint texture)
1867{
1868    // Simple pass-through to State's detachTexture method, as textures do not require
1869    // allocation map management either here or in the resource manager at detach time.
1870    // Zero textures are held by the Context, and we don't attempt to request them from
1871    // the State.
1872    mState.detachTexture(texture);
1873}
1874
1875void Context::detachBuffer(GLuint buffer)
1876{
1877    // Buffer detachment is handled by Context, because the buffer must also be
1878    // attached from any VAOs in existence, and Context holds the VAO map.
1879
1880    // [OpenGL ES 2.0.24] section 2.9 page 22:
1881    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
1882    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
1883
1884    mState.removeArrayBufferBinding(buffer);
1885
1886    // mark as freed among the vertex array objects
1887    for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
1888    {
1889        vaoIt->second->detachBuffer(buffer);
1890    }
1891}
1892
1893void Context::detachFramebuffer(GLuint framebuffer)
1894{
1895    // Framebuffer detachment is handled by Context, because 0 is a valid
1896    // Framebuffer object, and a pointer to it must be passed from Context
1897    // to State at binding time.
1898
1899    // [OpenGL ES 2.0.24] section 4.4 page 107:
1900    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
1901    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
1902
1903    if (mState.removeReadFramebufferBinding(framebuffer))
1904    {
1905        bindReadFramebuffer(0);
1906    }
1907
1908    if (mState.removeDrawFramebufferBinding(framebuffer))
1909    {
1910        bindDrawFramebuffer(0);
1911    }
1912}
1913
1914void Context::detachRenderbuffer(GLuint renderbuffer)
1915{
1916    mState.detachRenderbuffer(renderbuffer);
1917}
1918
1919void Context::detachVertexArray(GLuint vertexArray)
1920{
1921    // Vertex array detachment is handled by Context, because 0 is a valid
1922    // VAO, and a pointer to it must be passed from Context to State at
1923    // binding time.
1924
1925    // [OpenGL ES 3.0.2] section 2.10 page 43:
1926    // If a vertex array object that is currently bound is deleted, the binding
1927    // for that object reverts to zero and the default vertex array becomes current.
1928    if (mState.removeVertexArrayBinding(vertexArray))
1929    {
1930        bindVertexArray(0);
1931    }
1932}
1933
1934void Context::detachTransformFeedback(GLuint transformFeedback)
1935{
1936    mState.detachTransformFeedback(transformFeedback);
1937}
1938
1939void Context::detachSampler(GLuint sampler)
1940{
1941    mState.detachSampler(sampler);
1942}
1943
1944Texture *Context::getIncompleteTexture(GLenum type)
1945{
1946    if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
1947    {
1948        const GLubyte color[] = { 0, 0, 0, 255 };
1949        const PixelUnpackState incompleteUnpackState(1);
1950
1951        Texture* t = NULL;
1952        switch (type)
1953        {
1954          default:
1955            UNREACHABLE();
1956            // default falls through to TEXTURE_2D
1957
1958          case GL_TEXTURE_2D:
1959            {
1960                Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
1961                incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1962                t = incomplete2d;
1963            }
1964            break;
1965
1966          case GL_TEXTURE_CUBE_MAP:
1967            {
1968              TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
1969
1970              incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1971              incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1972              incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1973              incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1974              incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1975              incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1976
1977              t = incompleteCube;
1978            }
1979            break;
1980
1981          case GL_TEXTURE_3D:
1982            {
1983                Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
1984                incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1985
1986                t = incomplete3d;
1987            }
1988            break;
1989
1990          case GL_TEXTURE_2D_ARRAY:
1991            {
1992                Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
1993                incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
1994
1995                t = incomplete2darray;
1996            }
1997            break;
1998        }
1999
2000        mIncompleteTextures[type].set(t);
2001    }
2002
2003    return mIncompleteTextures[type].get();
2004}
2005
2006bool Context::skipDraw(GLenum drawMode)
2007{
2008    if (drawMode == GL_POINTS)
2009    {
2010        // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
2011        // which affects varying interpolation. Since the value of gl_PointSize is
2012        // undefined when not written, just skip drawing to avoid unexpected results.
2013        if (!mState.getCurrentProgramBinary()->usesPointSize())
2014        {
2015            // This is stictly speaking not an error, but developers should be
2016            // notified of risking undefined behavior.
2017            ERR("Point rendering without writing to gl_PointSize.");
2018
2019            return true;
2020        }
2021    }
2022    else if (IsTriangleMode(drawMode))
2023    {
2024        if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
2025        {
2026            return true;
2027        }
2028    }
2029
2030    return false;
2031}
2032
2033void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2034{
2035    mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
2036}
2037
2038void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
2039{
2040    mResourceManager->checkSamplerAllocation(sampler);
2041
2042    Sampler *samplerObject = getSampler(sampler);
2043    ASSERT(samplerObject);
2044
2045    switch (pname)
2046    {
2047      case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
2048      case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
2049      case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
2050      case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
2051      case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
2052      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
2053      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
2054      case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
2055      case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
2056      default:                       UNREACHABLE(); break;
2057    }
2058}
2059
2060void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2061{
2062    mResourceManager->checkSamplerAllocation(sampler);
2063
2064    Sampler *samplerObject = getSampler(sampler);
2065    ASSERT(samplerObject);
2066
2067    switch (pname)
2068    {
2069      case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(uiround<GLenum>(param));       break;
2070      case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(uiround<GLenum>(param));       break;
2071      case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(uiround<GLenum>(param));           break;
2072      case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(uiround<GLenum>(param));           break;
2073      case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(uiround<GLenum>(param));           break;
2074      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                           break;
2075      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                           break;
2076      case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(uiround<GLenum>(param));  break;
2077      case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(uiround<GLenum>(param));  break;
2078      default:                       UNREACHABLE(); break;
2079    }
2080}
2081
2082GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
2083{
2084    mResourceManager->checkSamplerAllocation(sampler);
2085
2086    Sampler *samplerObject = getSampler(sampler);
2087    ASSERT(samplerObject);
2088
2089    switch (pname)
2090    {
2091      case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
2092      case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
2093      case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
2094      case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
2095      case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
2096      case GL_TEXTURE_MIN_LOD:       return uiround<GLint>(samplerObject->getMinLod());
2097      case GL_TEXTURE_MAX_LOD:       return uiround<GLint>(samplerObject->getMaxLod());
2098      case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
2099      case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
2100      default:                       UNREACHABLE(); return 0;
2101    }
2102}
2103
2104GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
2105{
2106    mResourceManager->checkSamplerAllocation(sampler);
2107
2108    Sampler *samplerObject = getSampler(sampler);
2109    ASSERT(samplerObject);
2110
2111    switch (pname)
2112    {
2113      case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
2114      case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
2115      case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
2116      case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
2117      case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
2118      case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
2119      case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
2120      case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
2121      case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
2122      default:                       UNREACHABLE(); return 0;
2123    }
2124}
2125
2126void Context::initRendererString()
2127{
2128    std::ostringstream rendererString;
2129    rendererString << "ANGLE (";
2130    rendererString << mRenderer->getRendererDescription();
2131    rendererString << ")";
2132
2133    mRendererString = MakeStaticString(rendererString.str());
2134}
2135
2136const std::string &Context::getRendererString() const
2137{
2138    return mRendererString;
2139}
2140
2141void Context::initExtensionStrings()
2142{
2143    mExtensionStrings = mExtensions.getStrings();
2144
2145    std::ostringstream combinedStringStream;
2146    std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
2147    mExtensionString = combinedStringStream.str();
2148}
2149
2150const std::string &Context::getExtensionString() const
2151{
2152    return mExtensionString;
2153}
2154
2155const std::string &Context::getExtensionString(size_t idx) const
2156{
2157    return mExtensionStrings[idx];
2158}
2159
2160size_t Context::getExtensionStringCount() const
2161{
2162    return mExtensionStrings.size();
2163}
2164
2165size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
2166{
2167    size_t serialCount = 0;
2168
2169    Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2170    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
2171    {
2172        FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
2173        if (attachment && attachment->isTexture())
2174        {
2175            Texture *texture = attachment->getTexture();
2176            (*outSerialArray)[serialCount++] = texture->getTextureSerial();
2177        }
2178    }
2179
2180    FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
2181    if (depthStencilAttachment && depthStencilAttachment->isTexture())
2182    {
2183        Texture *depthStencilTexture = depthStencilAttachment->getTexture();
2184        (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
2185    }
2186
2187    std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
2188
2189    return serialCount;
2190}
2191
2192void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2193                              GLbitfield mask, GLenum filter)
2194{
2195    Framebuffer *readFramebuffer = mState.getReadFramebuffer();
2196    Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
2197
2198    bool blitRenderTarget = false;
2199    bool blitDepth = false;
2200    bool blitStencil = false;
2201    if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
2202    {
2203        blitRenderTarget = true;
2204    }
2205    if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2206    {
2207        blitStencil = true;
2208    }
2209    if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2210    {
2211        blitDepth = true;
2212    }
2213
2214    Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
2215    Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
2216    if (blitRenderTarget || blitDepth || blitStencil)
2217    {
2218        const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
2219        mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
2220                            blitRenderTarget, blitDepth, blitStencil, filter);
2221    }
2222}
2223
2224void Context::releaseShaderCompiler()
2225{
2226    mRenderer->releaseShaderCompiler();
2227}
2228
2229void Context::initCaps(GLuint clientVersion)
2230{
2231    mCaps = mRenderer->getRendererCaps();
2232
2233    mExtensions = mRenderer->getRendererExtensions();
2234
2235    if (clientVersion < 3)
2236    {
2237        // Disable ES3+ extensions
2238        mExtensions.colorBufferFloat = false;
2239    }
2240
2241    if (clientVersion > 2)
2242    {
2243        // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
2244        //mExtensions.sRGB = false;
2245    }
2246
2247    // Apply implementation limits
2248    mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
2249    mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
2250    mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2251
2252    mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
2253
2254    GLuint maxSamples = 0;
2255    mCaps.compressedTextureFormats.clear();
2256
2257    const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
2258    for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
2259    {
2260        GLenum format = i->first;
2261        TextureCaps formatCaps = i->second;
2262
2263        const InternalFormat &formatInfo = GetInternalFormatInfo(format);
2264        if (formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions))
2265        {
2266            // Update the format caps based on the client version and extensions
2267            formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions);
2268            formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions);
2269
2270            // OpenGL ES does not support multisampling with integer formats
2271            if (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
2272            {
2273                formatCaps.sampleCounts.clear();
2274            }
2275            maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
2276
2277            if (formatInfo.compressed)
2278            {
2279                mCaps.compressedTextureFormats.push_back(format);
2280            }
2281
2282            mTextureCaps.insert(format, formatCaps);
2283        }
2284    }
2285
2286    mExtensions.maxSamples = maxSamples;
2287}
2288
2289}
2290
2291extern "C"
2292{
2293gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
2294{
2295    return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
2296}
2297
2298void glDestroyContext(gl::Context *context)
2299{
2300    delete context;
2301
2302    if (context == gl::getContext())
2303    {
2304        gl::makeCurrent(NULL, NULL, NULL);
2305    }
2306}
2307
2308void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
2309{
2310    gl::makeCurrent(context, display, surface);
2311}
2312
2313gl::Context *glGetCurrentContext()
2314{
2315    return gl::getContext();
2316}
2317
2318}
2319