1#include "precompiled.h"
2//
3// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4// 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
13#include "libGLESv2/main.h"
14#include "libGLESv2/utilities.h"
15#include "libGLESv2/Buffer.h"
16#include "libGLESv2/Fence.h"
17#include "libGLESv2/Framebuffer.h"
18#include "libGLESv2/Renderbuffer.h"
19#include "libGLESv2/Program.h"
20#include "libGLESv2/ProgramBinary.h"
21#include "libGLESv2/Query.h"
22#include "libGLESv2/Texture.h"
23#include "libGLESv2/ResourceManager.h"
24#include "libGLESv2/renderer/IndexDataManager.h"
25#include "libGLESv2/renderer/RenderTarget.h"
26#include "libGLESv2/renderer/Renderer.h"
27
28#include "libEGL/Surface.h"
29
30#undef near
31#undef far
32
33namespace gl
34{
35static const char* makeStaticString(const std::string& str)
36{
37    static std::set<std::string> strings;
38    std::set<std::string>::iterator it = strings.find(str);
39    if (it != strings.end())
40      return it->c_str();
41
42    return strings.insert(str).first->c_str();
43}
44
45Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
46{
47    ASSERT(robustAccess == false);   // Unimplemented
48
49    mFenceHandleAllocator.setBaseHandle(0);
50
51    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
52
53    mState.depthClearValue = 1.0f;
54    mState.stencilClearValue = 0;
55
56    mState.rasterizer.cullFace = false;
57    mState.rasterizer.cullMode = GL_BACK;
58    mState.rasterizer.frontFace = GL_CCW;
59    mState.rasterizer.polygonOffsetFill = false;
60    mState.rasterizer.polygonOffsetFactor = 0.0f;
61    mState.rasterizer.polygonOffsetUnits = 0.0f;
62    mState.rasterizer.pointDrawMode = false;
63    mState.rasterizer.multiSample = false;
64    mState.scissorTest = false;
65    mState.scissor.x = 0;
66    mState.scissor.y = 0;
67    mState.scissor.width = 0;
68    mState.scissor.height = 0;
69
70    mState.blend.blend = false;
71    mState.blend.sourceBlendRGB = GL_ONE;
72    mState.blend.sourceBlendAlpha = GL_ONE;
73    mState.blend.destBlendRGB = GL_ZERO;
74    mState.blend.destBlendAlpha = GL_ZERO;
75    mState.blend.blendEquationRGB = GL_FUNC_ADD;
76    mState.blend.blendEquationAlpha = GL_FUNC_ADD;
77    mState.blend.sampleAlphaToCoverage = false;
78    mState.blend.dither = true;
79
80    mState.blendColor.red = 0;
81    mState.blendColor.green = 0;
82    mState.blendColor.blue = 0;
83    mState.blendColor.alpha = 0;
84
85    mState.depthStencil.depthTest = false;
86    mState.depthStencil.depthFunc = GL_LESS;
87    mState.depthStencil.depthMask = true;
88    mState.depthStencil.stencilTest = false;
89    mState.depthStencil.stencilFunc = GL_ALWAYS;
90    mState.depthStencil.stencilMask = -1;
91    mState.depthStencil.stencilWritemask = -1;
92    mState.depthStencil.stencilBackFunc = GL_ALWAYS;
93    mState.depthStencil.stencilBackMask = - 1;
94    mState.depthStencil.stencilBackWritemask = -1;
95    mState.depthStencil.stencilFail = GL_KEEP;
96    mState.depthStencil.stencilPassDepthFail = GL_KEEP;
97    mState.depthStencil.stencilPassDepthPass = GL_KEEP;
98    mState.depthStencil.stencilBackFail = GL_KEEP;
99    mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
100    mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
101
102    mState.stencilRef = 0;
103    mState.stencilBackRef = 0;
104
105    mState.sampleCoverage = false;
106    mState.sampleCoverageValue = 1.0f;
107    mState.sampleCoverageInvert = false;
108    mState.generateMipmapHint = GL_DONT_CARE;
109    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
110
111    mState.lineWidth = 1.0f;
112
113    mState.viewport.x = 0;
114    mState.viewport.y = 0;
115    mState.viewport.width = 0;
116    mState.viewport.height = 0;
117    mState.zNear = 0.0f;
118    mState.zFar = 1.0f;
119
120    mState.blend.colorMaskRed = true;
121    mState.blend.colorMaskGreen = true;
122    mState.blend.colorMaskBlue = true;
123    mState.blend.colorMaskAlpha = true;
124
125    if (shareContext != NULL)
126    {
127        mResourceManager = shareContext->mResourceManager;
128        mResourceManager->addRef();
129    }
130    else
131    {
132        mResourceManager = new ResourceManager(mRenderer);
133    }
134
135    // [OpenGL ES 2.0.24] section 3.7 page 83:
136    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
137    // and cube map texture state vectors respectively associated with them.
138    // In order that access to these initial textures not be lost, they are treated as texture
139    // objects all of whose names are 0.
140
141    mTexture2DZero.set(new Texture2D(mRenderer, 0));
142    mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
143
144    mState.activeSampler = 0;
145    bindArrayBuffer(0);
146    bindElementArrayBuffer(0);
147    bindTextureCubeMap(0);
148    bindTexture2D(0);
149    bindReadFramebuffer(0);
150    bindDrawFramebuffer(0);
151    bindRenderbuffer(0);
152
153    mState.currentProgram = 0;
154    mCurrentProgramBinary.set(NULL);
155
156    mState.packAlignment = 4;
157    mState.unpackAlignment = 4;
158    mState.packReverseRowOrder = false;
159
160    mExtensionString = NULL;
161    mRendererString = NULL;
162
163    mInvalidEnum = false;
164    mInvalidValue = false;
165    mInvalidOperation = false;
166    mOutOfMemory = false;
167    mInvalidFramebufferOperation = false;
168
169    mHasBeenCurrent = false;
170    mContextLost = false;
171    mResetStatus = GL_NO_ERROR;
172    mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
173    mRobustAccess = robustAccess;
174
175    mSupportsBGRATextures = false;
176    mSupportsDXT1Textures = false;
177    mSupportsDXT3Textures = false;
178    mSupportsDXT5Textures = false;
179    mSupportsEventQueries = false;
180    mSupportsOcclusionQueries = false;
181    mNumCompressedTextureFormats = 0;
182}
183
184Context::~Context()
185{
186    if (mState.currentProgram != 0)
187    {
188        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
189        if (programObject)
190        {
191            programObject->release();
192        }
193        mState.currentProgram = 0;
194    }
195    mCurrentProgramBinary.set(NULL);
196
197    while (!mFramebufferMap.empty())
198    {
199        deleteFramebuffer(mFramebufferMap.begin()->first);
200    }
201
202    while (!mFenceMap.empty())
203    {
204        deleteFence(mFenceMap.begin()->first);
205    }
206
207    while (!mQueryMap.empty())
208    {
209        deleteQuery(mQueryMap.begin()->first);
210    }
211
212    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
213    {
214        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
215        {
216            mState.samplerTexture[type][sampler].set(NULL);
217        }
218    }
219
220    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
221    {
222        mIncompleteTextures[type].set(NULL);
223    }
224
225    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226    {
227        mState.vertexAttribute[i].mBoundBuffer.set(NULL);
228    }
229
230    for (int i = 0; i < QUERY_TYPE_COUNT; i++)
231    {
232        mState.activeQuery[i].set(NULL);
233    }
234
235    mState.arrayBuffer.set(NULL);
236    mState.elementArrayBuffer.set(NULL);
237    mState.renderbuffer.set(NULL);
238
239    mTexture2DZero.set(NULL);
240    mTextureCubeMapZero.set(NULL);
241
242    mResourceManager->release();
243}
244
245void Context::makeCurrent(egl::Surface *surface)
246{
247    if (!mHasBeenCurrent)
248    {
249        mMajorShaderModel = mRenderer->getMajorShaderModel();
250        mMaximumPointSize = mRenderer->getMaxPointSize();
251        mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
252        mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
253        mSupportsInstancing = mRenderer->getInstancingSupport();
254
255        mMaxViewportDimension = mRenderer->getMaxViewportDimension();
256        mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
257                                        (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
258        mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
259        mMaxRenderbufferDimension = mMaxTextureDimension;
260        mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
261        mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
262        TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
263              mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
264
265        mSupportsEventQueries = mRenderer->getEventQuerySupport();
266        mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
267        mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
268        mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
269        mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
270        mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
271        mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
272        mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
273        mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
274        mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
275        mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
276        mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
277        mSupports32bitIndices = mRenderer->get32BitIndexSupport();
278
279        mNumCompressedTextureFormats = 0;
280        if (supportsDXT1Textures())
281        {
282            mNumCompressedTextureFormats += 2;
283        }
284        if (supportsDXT3Textures())
285        {
286            mNumCompressedTextureFormats += 1;
287        }
288        if (supportsDXT5Textures())
289        {
290            mNumCompressedTextureFormats += 1;
291        }
292
293        initExtensionString();
294        initRendererString();
295
296        mState.viewport.x = 0;
297        mState.viewport.y = 0;
298        mState.viewport.width = surface->getWidth();
299        mState.viewport.height = surface->getHeight();
300
301        mState.scissor.x = 0;
302        mState.scissor.y = 0;
303        mState.scissor.width = surface->getWidth();
304        mState.scissor.height = surface->getHeight();
305
306        mHasBeenCurrent = true;
307    }
308
309    // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
310    rx::SwapChain *swapchain = surface->getSwapChain();
311
312    Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
313    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
314    Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
315
316    setFramebufferZero(framebufferZero);
317}
318
319// NOTE: this function should not assume that this context is current!
320void Context::markContextLost()
321{
322    if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
323        mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
324    mContextLost = true;
325}
326
327bool Context::isContextLost()
328{
329    return mContextLost;
330}
331
332void Context::setClearColor(float red, float green, float blue, float alpha)
333{
334    mState.colorClearValue.red = red;
335    mState.colorClearValue.green = green;
336    mState.colorClearValue.blue = blue;
337    mState.colorClearValue.alpha = alpha;
338}
339
340void Context::setClearDepth(float depth)
341{
342    mState.depthClearValue = depth;
343}
344
345void Context::setClearStencil(int stencil)
346{
347    mState.stencilClearValue = stencil;
348}
349
350void Context::setCullFace(bool enabled)
351{
352    mState.rasterizer.cullFace = enabled;
353}
354
355bool Context::isCullFaceEnabled() const
356{
357    return mState.rasterizer.cullFace;
358}
359
360void Context::setCullMode(GLenum mode)
361{
362    mState.rasterizer.cullMode = mode;
363}
364
365void Context::setFrontFace(GLenum front)
366{
367    mState.rasterizer.frontFace = front;
368}
369
370void Context::setDepthTest(bool enabled)
371{
372    mState.depthStencil.depthTest = enabled;
373}
374
375bool Context::isDepthTestEnabled() const
376{
377    return mState.depthStencil.depthTest;
378}
379
380void Context::setDepthFunc(GLenum depthFunc)
381{
382     mState.depthStencil.depthFunc = depthFunc;
383}
384
385void Context::setDepthRange(float zNear, float zFar)
386{
387    mState.zNear = zNear;
388    mState.zFar = zFar;
389}
390
391void Context::setBlend(bool enabled)
392{
393    mState.blend.blend = enabled;
394}
395
396bool Context::isBlendEnabled() const
397{
398    return mState.blend.blend;
399}
400
401void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
402{
403    mState.blend.sourceBlendRGB = sourceRGB;
404    mState.blend.destBlendRGB = destRGB;
405    mState.blend.sourceBlendAlpha = sourceAlpha;
406    mState.blend.destBlendAlpha = destAlpha;
407}
408
409void Context::setBlendColor(float red, float green, float blue, float alpha)
410{
411    mState.blendColor.red = red;
412    mState.blendColor.green = green;
413    mState.blendColor.blue = blue;
414    mState.blendColor.alpha = alpha;
415}
416
417void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
418{
419    mState.blend.blendEquationRGB = rgbEquation;
420    mState.blend.blendEquationAlpha = alphaEquation;
421}
422
423void Context::setStencilTest(bool enabled)
424{
425    mState.depthStencil.stencilTest = enabled;
426}
427
428bool Context::isStencilTestEnabled() const
429{
430    return mState.depthStencil.stencilTest;
431}
432
433void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
434{
435    mState.depthStencil.stencilFunc = stencilFunc;
436    mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
437    mState.depthStencil.stencilMask = stencilMask;
438}
439
440void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
441{
442    mState.depthStencil.stencilBackFunc = stencilBackFunc;
443    mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
444    mState.depthStencil.stencilBackMask = stencilBackMask;
445}
446
447void Context::setStencilWritemask(GLuint stencilWritemask)
448{
449    mState.depthStencil.stencilWritemask = stencilWritemask;
450}
451
452void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
453{
454    mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
455}
456
457void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
458{
459    mState.depthStencil.stencilFail = stencilFail;
460    mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
461    mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
462}
463
464void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
465{
466    mState.depthStencil.stencilBackFail = stencilBackFail;
467    mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
468    mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
469}
470
471void Context::setPolygonOffsetFill(bool enabled)
472{
473     mState.rasterizer.polygonOffsetFill = enabled;
474}
475
476bool Context::isPolygonOffsetFillEnabled() const
477{
478    return mState.rasterizer.polygonOffsetFill;
479}
480
481void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
482{
483    // An application can pass NaN values here, so handle this gracefully
484    mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
485    mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
486}
487
488void Context::setSampleAlphaToCoverage(bool enabled)
489{
490    mState.blend.sampleAlphaToCoverage = enabled;
491}
492
493bool Context::isSampleAlphaToCoverageEnabled() const
494{
495    return mState.blend.sampleAlphaToCoverage;
496}
497
498void Context::setSampleCoverage(bool enabled)
499{
500    mState.sampleCoverage = enabled;
501}
502
503bool Context::isSampleCoverageEnabled() const
504{
505    return mState.sampleCoverage;
506}
507
508void Context::setSampleCoverageParams(GLclampf value, bool invert)
509{
510    mState.sampleCoverageValue = value;
511    mState.sampleCoverageInvert = invert;
512}
513
514void Context::setScissorTest(bool enabled)
515{
516    mState.scissorTest = enabled;
517}
518
519bool Context::isScissorTestEnabled() const
520{
521    return mState.scissorTest;
522}
523
524void Context::setDither(bool enabled)
525{
526    mState.blend.dither = enabled;
527}
528
529bool Context::isDitherEnabled() const
530{
531    return mState.blend.dither;
532}
533
534void Context::setLineWidth(GLfloat width)
535{
536    mState.lineWidth = width;
537}
538
539void Context::setGenerateMipmapHint(GLenum hint)
540{
541    mState.generateMipmapHint = hint;
542}
543
544void Context::setFragmentShaderDerivativeHint(GLenum hint)
545{
546    mState.fragmentShaderDerivativeHint = hint;
547    // TODO: Propagate the hint to shader translator so we can write
548    // ddx, ddx_coarse, or ddx_fine depending on the hint.
549    // Ignore for now. It is valid for implementations to ignore hint.
550}
551
552void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
553{
554    mState.viewport.x = x;
555    mState.viewport.y = y;
556    mState.viewport.width = width;
557    mState.viewport.height = height;
558}
559
560void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
561{
562    mState.scissor.x = x;
563    mState.scissor.y = y;
564    mState.scissor.width = width;
565    mState.scissor.height = height;
566}
567
568void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
569{
570    mState.blend.colorMaskRed = red;
571    mState.blend.colorMaskGreen = green;
572    mState.blend.colorMaskBlue = blue;
573    mState.blend.colorMaskAlpha = alpha;
574}
575
576void Context::setDepthMask(bool mask)
577{
578    mState.depthStencil.depthMask = mask;
579}
580
581void Context::setActiveSampler(unsigned int active)
582{
583    mState.activeSampler = active;
584}
585
586GLuint Context::getReadFramebufferHandle() const
587{
588    return mState.readFramebuffer;
589}
590
591GLuint Context::getDrawFramebufferHandle() const
592{
593    return mState.drawFramebuffer;
594}
595
596GLuint Context::getRenderbufferHandle() const
597{
598    return mState.renderbuffer.id();
599}
600
601GLuint Context::getArrayBufferHandle() const
602{
603    return mState.arrayBuffer.id();
604}
605
606GLuint Context::getActiveQuery(GLenum target) const
607{
608    Query *queryObject = NULL;
609
610    switch (target)
611    {
612      case GL_ANY_SAMPLES_PASSED_EXT:
613        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
614        break;
615      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
616        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
617        break;
618      default:
619        ASSERT(false);
620    }
621
622    if (queryObject)
623    {
624        return queryObject->id();
625    }
626    else
627    {
628        return 0;
629    }
630}
631
632void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
633{
634    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
635}
636
637const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
638{
639    return mState.vertexAttribute[attribNum];
640}
641
642void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
643                                   GLsizei stride, const void *pointer)
644{
645    mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
646    mState.vertexAttribute[attribNum].mSize = size;
647    mState.vertexAttribute[attribNum].mType = type;
648    mState.vertexAttribute[attribNum].mNormalized = normalized;
649    mState.vertexAttribute[attribNum].mStride = stride;
650    mState.vertexAttribute[attribNum].mPointer = pointer;
651}
652
653const void *Context::getVertexAttribPointer(unsigned int attribNum) const
654{
655    return mState.vertexAttribute[attribNum].mPointer;
656}
657
658void Context::setPackAlignment(GLint alignment)
659{
660    mState.packAlignment = alignment;
661}
662
663GLint Context::getPackAlignment() const
664{
665    return mState.packAlignment;
666}
667
668void Context::setUnpackAlignment(GLint alignment)
669{
670    mState.unpackAlignment = alignment;
671}
672
673GLint Context::getUnpackAlignment() const
674{
675    return mState.unpackAlignment;
676}
677
678void Context::setPackReverseRowOrder(bool reverseRowOrder)
679{
680    mState.packReverseRowOrder = reverseRowOrder;
681}
682
683bool Context::getPackReverseRowOrder() const
684{
685    return mState.packReverseRowOrder;
686}
687
688GLuint Context::createBuffer()
689{
690    return mResourceManager->createBuffer();
691}
692
693GLuint Context::createProgram()
694{
695    return mResourceManager->createProgram();
696}
697
698GLuint Context::createShader(GLenum type)
699{
700    return mResourceManager->createShader(type);
701}
702
703GLuint Context::createTexture()
704{
705    return mResourceManager->createTexture();
706}
707
708GLuint Context::createRenderbuffer()
709{
710    return mResourceManager->createRenderbuffer();
711}
712
713// Returns an unused framebuffer name
714GLuint Context::createFramebuffer()
715{
716    GLuint handle = mFramebufferHandleAllocator.allocate();
717
718    mFramebufferMap[handle] = NULL;
719
720    return handle;
721}
722
723GLuint Context::createFence()
724{
725    GLuint handle = mFenceHandleAllocator.allocate();
726
727    mFenceMap[handle] = new Fence(mRenderer);
728
729    return handle;
730}
731
732// Returns an unused query name
733GLuint Context::createQuery()
734{
735    GLuint handle = mQueryHandleAllocator.allocate();
736
737    mQueryMap[handle] = NULL;
738
739    return handle;
740}
741
742void Context::deleteBuffer(GLuint buffer)
743{
744    if (mResourceManager->getBuffer(buffer))
745    {
746        detachBuffer(buffer);
747    }
748
749    mResourceManager->deleteBuffer(buffer);
750}
751
752void Context::deleteShader(GLuint shader)
753{
754    mResourceManager->deleteShader(shader);
755}
756
757void Context::deleteProgram(GLuint program)
758{
759    mResourceManager->deleteProgram(program);
760}
761
762void Context::deleteTexture(GLuint texture)
763{
764    if (mResourceManager->getTexture(texture))
765    {
766        detachTexture(texture);
767    }
768
769    mResourceManager->deleteTexture(texture);
770}
771
772void Context::deleteRenderbuffer(GLuint renderbuffer)
773{
774    if (mResourceManager->getRenderbuffer(renderbuffer))
775    {
776        detachRenderbuffer(renderbuffer);
777    }
778
779    mResourceManager->deleteRenderbuffer(renderbuffer);
780}
781
782void Context::deleteFramebuffer(GLuint framebuffer)
783{
784    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
785
786    if (framebufferObject != mFramebufferMap.end())
787    {
788        detachFramebuffer(framebuffer);
789
790        mFramebufferHandleAllocator.release(framebufferObject->first);
791        delete framebufferObject->second;
792        mFramebufferMap.erase(framebufferObject);
793    }
794}
795
796void Context::deleteFence(GLuint fence)
797{
798    FenceMap::iterator fenceObject = mFenceMap.find(fence);
799
800    if (fenceObject != mFenceMap.end())
801    {
802        mFenceHandleAllocator.release(fenceObject->first);
803        delete fenceObject->second;
804        mFenceMap.erase(fenceObject);
805    }
806}
807
808void Context::deleteQuery(GLuint query)
809{
810    QueryMap::iterator queryObject = mQueryMap.find(query);
811    if (queryObject != mQueryMap.end())
812    {
813        mQueryHandleAllocator.release(queryObject->first);
814        if (queryObject->second)
815        {
816            queryObject->second->release();
817        }
818        mQueryMap.erase(queryObject);
819    }
820}
821
822Buffer *Context::getBuffer(GLuint handle)
823{
824    return mResourceManager->getBuffer(handle);
825}
826
827Shader *Context::getShader(GLuint handle)
828{
829    return mResourceManager->getShader(handle);
830}
831
832Program *Context::getProgram(GLuint handle)
833{
834    return mResourceManager->getProgram(handle);
835}
836
837Texture *Context::getTexture(GLuint handle)
838{
839    return mResourceManager->getTexture(handle);
840}
841
842Renderbuffer *Context::getRenderbuffer(GLuint handle)
843{
844    return mResourceManager->getRenderbuffer(handle);
845}
846
847Framebuffer *Context::getReadFramebuffer()
848{
849    return getFramebuffer(mState.readFramebuffer);
850}
851
852Framebuffer *Context::getDrawFramebuffer()
853{
854    return mBoundDrawFramebuffer;
855}
856
857void Context::bindArrayBuffer(unsigned int buffer)
858{
859    mResourceManager->checkBufferAllocation(buffer);
860
861    mState.arrayBuffer.set(getBuffer(buffer));
862}
863
864void Context::bindElementArrayBuffer(unsigned int buffer)
865{
866    mResourceManager->checkBufferAllocation(buffer);
867
868    mState.elementArrayBuffer.set(getBuffer(buffer));
869}
870
871void Context::bindTexture2D(GLuint texture)
872{
873    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
874
875    mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
876}
877
878void Context::bindTextureCubeMap(GLuint texture)
879{
880    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
881
882    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
883}
884
885void Context::bindReadFramebuffer(GLuint framebuffer)
886{
887    if (!getFramebuffer(framebuffer))
888    {
889        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
890    }
891
892    mState.readFramebuffer = framebuffer;
893}
894
895void Context::bindDrawFramebuffer(GLuint framebuffer)
896{
897    if (!getFramebuffer(framebuffer))
898    {
899        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
900    }
901
902    mState.drawFramebuffer = framebuffer;
903
904    mBoundDrawFramebuffer = getFramebuffer(framebuffer);
905}
906
907void Context::bindRenderbuffer(GLuint renderbuffer)
908{
909    mResourceManager->checkRenderbufferAllocation(renderbuffer);
910
911    mState.renderbuffer.set(getRenderbuffer(renderbuffer));
912}
913
914void Context::useProgram(GLuint program)
915{
916    GLuint priorProgram = mState.currentProgram;
917    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
918
919    if (priorProgram != program)
920    {
921        Program *newProgram = mResourceManager->getProgram(program);
922        Program *oldProgram = mResourceManager->getProgram(priorProgram);
923        mCurrentProgramBinary.set(NULL);
924
925        if (newProgram)
926        {
927            newProgram->addRef();
928            mCurrentProgramBinary.set(newProgram->getProgramBinary());
929        }
930
931        if (oldProgram)
932        {
933            oldProgram->release();
934        }
935    }
936}
937
938void Context::linkProgram(GLuint program)
939{
940    Program *programObject = mResourceManager->getProgram(program);
941
942    bool linked = programObject->link();
943
944    // if the current program was relinked successfully we
945    // need to install the new executables
946    if (linked && program == mState.currentProgram)
947    {
948        mCurrentProgramBinary.set(programObject->getProgramBinary());
949    }
950}
951
952void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
953{
954    Program *programObject = mResourceManager->getProgram(program);
955
956    bool loaded = programObject->setProgramBinary(binary, length);
957
958    // if the current program was reloaded successfully we
959    // need to install the new executables
960    if (loaded && program == mState.currentProgram)
961    {
962        mCurrentProgramBinary.set(programObject->getProgramBinary());
963    }
964
965}
966
967void Context::beginQuery(GLenum target, GLuint query)
968{
969    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
970    // of zero, if the active query object name for <target> is non-zero (for the
971    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
972    // the active query for either target is non-zero), if <id> is the name of an
973    // existing query object whose type does not match <target>, or if <id> is the
974    // active query object name for any query type, the error INVALID_OPERATION is
975    // generated.
976
977    // Ensure no other queries are active
978    // NOTE: If other queries than occlusion are supported, we will need to check
979    // separately that:
980    //    a) The query ID passed is not the current active query for any target/type
981    //    b) There are no active queries for the requested target (and in the case
982    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
983    //       no query may be active for either if glBeginQuery targets either.
984    for (int i = 0; i < QUERY_TYPE_COUNT; i++)
985    {
986        if (mState.activeQuery[i].get() != NULL)
987        {
988            return gl::error(GL_INVALID_OPERATION);
989        }
990    }
991
992    QueryType qType;
993    switch (target)
994    {
995      case GL_ANY_SAMPLES_PASSED_EXT:
996        qType = QUERY_ANY_SAMPLES_PASSED;
997        break;
998      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
999        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1000        break;
1001      default:
1002        ASSERT(false);
1003        return;
1004    }
1005
1006    Query *queryObject = getQuery(query, true, target);
1007
1008    // check that name was obtained with glGenQueries
1009    if (!queryObject)
1010    {
1011        return gl::error(GL_INVALID_OPERATION);
1012    }
1013
1014    // check for type mismatch
1015    if (queryObject->getType() != target)
1016    {
1017        return gl::error(GL_INVALID_OPERATION);
1018    }
1019
1020    // set query as active for specified target
1021    mState.activeQuery[qType].set(queryObject);
1022
1023    // begin query
1024    queryObject->begin();
1025}
1026
1027void Context::endQuery(GLenum target)
1028{
1029    QueryType qType;
1030
1031    switch (target)
1032    {
1033      case GL_ANY_SAMPLES_PASSED_EXT:
1034        qType = QUERY_ANY_SAMPLES_PASSED;
1035        break;
1036      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1037        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1038        break;
1039      default:
1040        ASSERT(false);
1041        return;
1042    }
1043
1044    Query *queryObject = mState.activeQuery[qType].get();
1045
1046    if (queryObject == NULL)
1047    {
1048        return gl::error(GL_INVALID_OPERATION);
1049    }
1050
1051    queryObject->end();
1052
1053    mState.activeQuery[qType].set(NULL);
1054}
1055
1056void Context::setFramebufferZero(Framebuffer *buffer)
1057{
1058    delete mFramebufferMap[0];
1059    mFramebufferMap[0] = buffer;
1060    if (mState.drawFramebuffer == 0)
1061    {
1062        mBoundDrawFramebuffer = buffer;
1063    }
1064}
1065
1066void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
1067{
1068    RenderbufferStorage *renderbuffer = NULL;
1069    switch (internalformat)
1070    {
1071      case GL_DEPTH_COMPONENT16:
1072        renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
1073        break;
1074      case GL_RGBA4:
1075      case GL_RGB5_A1:
1076      case GL_RGB565:
1077      case GL_RGB8_OES:
1078      case GL_RGBA8_OES:
1079        renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
1080        break;
1081      case GL_STENCIL_INDEX8:
1082        renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
1083        break;
1084      case GL_DEPTH24_STENCIL8_OES:
1085        renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
1086        break;
1087      default:
1088        UNREACHABLE(); return;
1089    }
1090
1091    Renderbuffer *renderbufferObject = mState.renderbuffer.get();
1092    renderbufferObject->setStorage(renderbuffer);
1093}
1094
1095Framebuffer *Context::getFramebuffer(unsigned int handle)
1096{
1097    FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
1098
1099    if (framebuffer == mFramebufferMap.end())
1100    {
1101        return NULL;
1102    }
1103    else
1104    {
1105        return framebuffer->second;
1106    }
1107}
1108
1109Fence *Context::getFence(unsigned int handle)
1110{
1111    FenceMap::iterator fence = mFenceMap.find(handle);
1112
1113    if (fence == mFenceMap.end())
1114    {
1115        return NULL;
1116    }
1117    else
1118    {
1119        return fence->second;
1120    }
1121}
1122
1123Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1124{
1125    QueryMap::iterator query = mQueryMap.find(handle);
1126
1127    if (query == mQueryMap.end())
1128    {
1129        return NULL;
1130    }
1131    else
1132    {
1133        if (!query->second && create)
1134        {
1135            query->second = new Query(mRenderer, type, handle);
1136            query->second->addRef();
1137        }
1138        return query->second;
1139    }
1140}
1141
1142Buffer *Context::getArrayBuffer()
1143{
1144    return mState.arrayBuffer.get();
1145}
1146
1147Buffer *Context::getElementArrayBuffer()
1148{
1149    return mState.elementArrayBuffer.get();
1150}
1151
1152ProgramBinary *Context::getCurrentProgramBinary()
1153{
1154    return mCurrentProgramBinary.get();
1155}
1156
1157Texture2D *Context::getTexture2D()
1158{
1159    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1160}
1161
1162TextureCubeMap *Context::getTextureCubeMap()
1163{
1164    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1165}
1166
1167Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1168{
1169    GLuint texid = mState.samplerTexture[type][sampler].id();
1170
1171    if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
1172    {
1173        switch (type)
1174        {
1175          default: UNREACHABLE();
1176          case TEXTURE_2D: return mTexture2DZero.get();
1177          case TEXTURE_CUBE: return mTextureCubeMapZero.get();
1178        }
1179    }
1180
1181    return mState.samplerTexture[type][sampler].get();
1182}
1183
1184bool Context::getBooleanv(GLenum pname, GLboolean *params)
1185{
1186    switch (pname)
1187    {
1188      case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
1189      case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
1190      case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
1191      case GL_COLOR_WRITEMASK:
1192        params[0] = mState.blend.colorMaskRed;
1193        params[1] = mState.blend.colorMaskGreen;
1194        params[2] = mState.blend.colorMaskBlue;
1195        params[3] = mState.blend.colorMaskAlpha;
1196        break;
1197      case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
1198      case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
1199      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
1200      case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
1201      case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
1202      case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
1203      case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
1204      case GL_BLEND:                     *params = mState.blend.blend;                  break;
1205      case GL_DITHER:                    *params = mState.blend.dither;                 break;
1206      case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
1207      default:
1208        return false;
1209    }
1210
1211    return true;
1212}
1213
1214bool Context::getFloatv(GLenum pname, GLfloat *params)
1215{
1216    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1217    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1218    // GetIntegerv as its native query function. As it would require conversion in any
1219    // case, this should make no difference to the calling application.
1220    switch (pname)
1221    {
1222      case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
1223      case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
1224      case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
1225      case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
1226      case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
1227      case GL_ALIASED_LINE_WIDTH_RANGE:
1228        params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
1229        params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
1230        break;
1231      case GL_ALIASED_POINT_SIZE_RANGE:
1232        params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
1233        params[1] = getMaximumPointSize();
1234        break;
1235      case GL_DEPTH_RANGE:
1236        params[0] = mState.zNear;
1237        params[1] = mState.zFar;
1238        break;
1239      case GL_COLOR_CLEAR_VALUE:
1240        params[0] = mState.colorClearValue.red;
1241        params[1] = mState.colorClearValue.green;
1242        params[2] = mState.colorClearValue.blue;
1243        params[3] = mState.colorClearValue.alpha;
1244        break;
1245      case GL_BLEND_COLOR:
1246        params[0] = mState.blendColor.red;
1247        params[1] = mState.blendColor.green;
1248        params[2] = mState.blendColor.blue;
1249        params[3] = mState.blendColor.alpha;
1250        break;
1251      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1252        if (!supportsTextureFilterAnisotropy())
1253        {
1254            return false;
1255        }
1256        *params = mMaxTextureAnisotropy;
1257        break;
1258      default:
1259        return false;
1260    }
1261
1262    return true;
1263}
1264
1265bool Context::getIntegerv(GLenum pname, GLint *params)
1266{
1267    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1268    {
1269        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1270
1271        if (colorAttachment >= mRenderer->getMaxRenderTargets())
1272        {
1273            // return true to stop further operation in the parent call
1274            return gl::error(GL_INVALID_OPERATION, true);
1275        }
1276
1277        Framebuffer *framebuffer = getDrawFramebuffer();
1278
1279        *params = framebuffer->getDrawBufferState(colorAttachment);
1280        return true;
1281    }
1282
1283    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1284    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1285    // GetIntegerv as its native query function. As it would require conversion in any
1286    // case, this should make no difference to the calling application. You may find it in
1287    // Context::getFloatv.
1288    switch (pname)
1289    {
1290      case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
1291      case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = mRenderer->getMaxVertexUniformVectors(); break;
1292      case GL_MAX_VARYING_VECTORS:              *params = mRenderer->getMaxVaryingVectors();    break;
1293      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
1294      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = mRenderer->getMaxVertexTextureImageUnits(); break;
1295      case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
1296      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = mRenderer->getMaxFragmentUniformVectors(); break;
1297      case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
1298      case GL_MAX_COLOR_ATTACHMENTS_EXT:        *params = mRenderer->getMaxRenderTargets();     break;
1299      case GL_MAX_DRAW_BUFFERS_EXT:             *params = mRenderer->getMaxRenderTargets();     break;
1300      case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1301      case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1302      case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.id();              break;
1303      case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.id();       break;
1304      //case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1305      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
1306      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
1307      case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.id();             break;
1308      case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1309      case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1310      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:     *params = mState.packReverseRowOrder;           break;
1311      case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1312      case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1313      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1314      case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1315      case GL_STENCIL_FUNC:                     *params = mState.depthStencil.stencilFunc;             break;
1316      case GL_STENCIL_REF:                      *params = mState.stencilRef;                           break;
1317      case GL_STENCIL_VALUE_MASK:               *params = mState.depthStencil.stencilMask;             break;
1318      case GL_STENCIL_BACK_FUNC:                *params = mState.depthStencil.stencilBackFunc;         break;
1319      case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                       break;
1320      case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.depthStencil.stencilBackMask;         break;
1321      case GL_STENCIL_FAIL:                     *params = mState.depthStencil.stencilFail;             break;
1322      case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.depthStencil.stencilPassDepthFail;    break;
1323      case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.depthStencil.stencilPassDepthPass;    break;
1324      case GL_STENCIL_BACK_FAIL:                *params = mState.depthStencil.stencilBackFail;         break;
1325      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.depthStencil.stencilBackPassDepthFail; break;
1326      case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.depthStencil.stencilBackPassDepthPass; break;
1327      case GL_DEPTH_FUNC:                       *params = mState.depthStencil.depthFunc;               break;
1328      case GL_BLEND_SRC_RGB:                    *params = mState.blend.sourceBlendRGB;                 break;
1329      case GL_BLEND_SRC_ALPHA:                  *params = mState.blend.sourceBlendAlpha;               break;
1330      case GL_BLEND_DST_RGB:                    *params = mState.blend.destBlendRGB;                   break;
1331      case GL_BLEND_DST_ALPHA:                  *params = mState.blend.destBlendAlpha;                 break;
1332      case GL_BLEND_EQUATION_RGB:               *params = mState.blend.blendEquationRGB;               break;
1333      case GL_BLEND_EQUATION_ALPHA:             *params = mState.blend.blendEquationAlpha;             break;
1334      case GL_STENCIL_WRITEMASK:                *params = mState.depthStencil.stencilWritemask;        break;
1335      case GL_STENCIL_BACK_WRITEMASK:           *params = mState.depthStencil.stencilBackWritemask;    break;
1336      case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1337      case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1338      case GL_MAX_TEXTURE_SIZE:                 *params = getMaximumTextureDimension();         break;
1339      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = getMaximumCubeTextureDimension();     break;
1340      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1341        params[0] = mNumCompressedTextureFormats;
1342        break;
1343      case GL_MAX_SAMPLES_ANGLE:
1344        {
1345            GLsizei maxSamples = getMaxSupportedSamples();
1346            if (maxSamples != 0)
1347            {
1348                *params = maxSamples;
1349            }
1350            else
1351            {
1352                return false;
1353            }
1354
1355            break;
1356        }
1357      case GL_SAMPLE_BUFFERS:
1358      case GL_SAMPLES:
1359        {
1360            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1361            if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1362            {
1363                switch (pname)
1364                {
1365                  case GL_SAMPLE_BUFFERS:
1366                    if (framebuffer->getSamples() != 0)
1367                    {
1368                        *params = 1;
1369                    }
1370                    else
1371                    {
1372                        *params = 0;
1373                    }
1374                    break;
1375                  case GL_SAMPLES:
1376                    *params = framebuffer->getSamples();
1377                    break;
1378                }
1379            }
1380            else
1381            {
1382                *params = 0;
1383            }
1384        }
1385        break;
1386      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1387      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1388        {
1389            GLenum format, type;
1390            if (getCurrentReadFormatType(&format, &type))
1391            {
1392                if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
1393                    *params = format;
1394                else
1395                    *params = type;
1396            }
1397        }
1398        break;
1399      case GL_MAX_VIEWPORT_DIMS:
1400        {
1401            params[0] = mMaxViewportDimension;
1402            params[1] = mMaxViewportDimension;
1403        }
1404        break;
1405      case GL_COMPRESSED_TEXTURE_FORMATS:
1406        {
1407            if (supportsDXT1Textures())
1408            {
1409                *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
1410                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1411            }
1412            if (supportsDXT3Textures())
1413            {
1414                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
1415            }
1416            if (supportsDXT5Textures())
1417            {
1418                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1419            }
1420        }
1421        break;
1422      case GL_VIEWPORT:
1423        params[0] = mState.viewport.x;
1424        params[1] = mState.viewport.y;
1425        params[2] = mState.viewport.width;
1426        params[3] = mState.viewport.height;
1427        break;
1428      case GL_SCISSOR_BOX:
1429        params[0] = mState.scissor.x;
1430        params[1] = mState.scissor.y;
1431        params[2] = mState.scissor.width;
1432        params[3] = mState.scissor.height;
1433        break;
1434      case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
1435      case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
1436      case GL_RED_BITS:
1437      case GL_GREEN_BITS:
1438      case GL_BLUE_BITS:
1439      case GL_ALPHA_BITS:
1440        {
1441            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1442            gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
1443
1444            if (colorbuffer)
1445            {
1446                switch (pname)
1447                {
1448                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
1449                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
1450                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
1451                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
1452                }
1453            }
1454            else
1455            {
1456                *params = 0;
1457            }
1458        }
1459        break;
1460      case GL_DEPTH_BITS:
1461        {
1462            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1463            gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1464
1465            if (depthbuffer)
1466            {
1467                *params = depthbuffer->getDepthSize();
1468            }
1469            else
1470            {
1471                *params = 0;
1472            }
1473        }
1474        break;
1475      case GL_STENCIL_BITS:
1476        {
1477            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1478            gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1479
1480            if (stencilbuffer)
1481            {
1482                *params = stencilbuffer->getStencilSize();
1483            }
1484            else
1485            {
1486                *params = 0;
1487            }
1488        }
1489        break;
1490      case GL_TEXTURE_BINDING_2D:
1491        {
1492            if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1493            {
1494                gl::error(GL_INVALID_OPERATION);
1495                return false;
1496            }
1497
1498            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1499        }
1500        break;
1501      case GL_TEXTURE_BINDING_CUBE_MAP:
1502        {
1503            if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1504            {
1505                gl::error(GL_INVALID_OPERATION);
1506                return false;
1507            }
1508
1509            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1510        }
1511        break;
1512      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1513        *params = mResetStrategy;
1514        break;
1515      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1516        *params = 1;
1517        break;
1518      case GL_PROGRAM_BINARY_FORMATS_OES:
1519        *params = GL_PROGRAM_BINARY_ANGLE;
1520        break;
1521      default:
1522        return false;
1523    }
1524
1525    return true;
1526}
1527
1528bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1529{
1530    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1531    {
1532        *type = GL_INT;
1533        *numParams = 1;
1534        return true;
1535    }
1536
1537    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1538    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1539    // to the fact that it is stored internally as a float, and so would require conversion
1540    // if returned from Context::getIntegerv. Since this conversion is already implemented
1541    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1542    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1543    // application.
1544    switch (pname)
1545    {
1546      case GL_COMPRESSED_TEXTURE_FORMATS:
1547        {
1548            *type = GL_INT;
1549            *numParams = mNumCompressedTextureFormats;
1550        }
1551        break;
1552      case GL_SHADER_BINARY_FORMATS:
1553        {
1554            *type = GL_INT;
1555            *numParams = 0;
1556        }
1557        break;
1558      case GL_MAX_VERTEX_ATTRIBS:
1559      case GL_MAX_VERTEX_UNIFORM_VECTORS:
1560      case GL_MAX_VARYING_VECTORS:
1561      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1562      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1563      case GL_MAX_TEXTURE_IMAGE_UNITS:
1564      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1565      case GL_MAX_RENDERBUFFER_SIZE:
1566      case GL_MAX_COLOR_ATTACHMENTS_EXT:
1567      case GL_MAX_DRAW_BUFFERS_EXT:
1568      case GL_NUM_SHADER_BINARY_FORMATS:
1569      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1570      case GL_ARRAY_BUFFER_BINDING:
1571      case GL_FRAMEBUFFER_BINDING:
1572      case GL_RENDERBUFFER_BINDING:
1573      case GL_CURRENT_PROGRAM:
1574      case GL_PACK_ALIGNMENT:
1575      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1576      case GL_UNPACK_ALIGNMENT:
1577      case GL_GENERATE_MIPMAP_HINT:
1578      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1579      case GL_RED_BITS:
1580      case GL_GREEN_BITS:
1581      case GL_BLUE_BITS:
1582      case GL_ALPHA_BITS:
1583      case GL_DEPTH_BITS:
1584      case GL_STENCIL_BITS:
1585      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1586      case GL_CULL_FACE_MODE:
1587      case GL_FRONT_FACE:
1588      case GL_ACTIVE_TEXTURE:
1589      case GL_STENCIL_FUNC:
1590      case GL_STENCIL_VALUE_MASK:
1591      case GL_STENCIL_REF:
1592      case GL_STENCIL_FAIL:
1593      case GL_STENCIL_PASS_DEPTH_FAIL:
1594      case GL_STENCIL_PASS_DEPTH_PASS:
1595      case GL_STENCIL_BACK_FUNC:
1596      case GL_STENCIL_BACK_VALUE_MASK:
1597      case GL_STENCIL_BACK_REF:
1598      case GL_STENCIL_BACK_FAIL:
1599      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1600      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1601      case GL_DEPTH_FUNC:
1602      case GL_BLEND_SRC_RGB:
1603      case GL_BLEND_SRC_ALPHA:
1604      case GL_BLEND_DST_RGB:
1605      case GL_BLEND_DST_ALPHA:
1606      case GL_BLEND_EQUATION_RGB:
1607      case GL_BLEND_EQUATION_ALPHA:
1608      case GL_STENCIL_WRITEMASK:
1609      case GL_STENCIL_BACK_WRITEMASK:
1610      case GL_STENCIL_CLEAR_VALUE:
1611      case GL_SUBPIXEL_BITS:
1612      case GL_MAX_TEXTURE_SIZE:
1613      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1614      case GL_SAMPLE_BUFFERS:
1615      case GL_SAMPLES:
1616      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1617      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1618      case GL_TEXTURE_BINDING_2D:
1619      case GL_TEXTURE_BINDING_CUBE_MAP:
1620      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1621      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1622      case GL_PROGRAM_BINARY_FORMATS_OES:
1623        {
1624            *type = GL_INT;
1625            *numParams = 1;
1626        }
1627        break;
1628      case GL_MAX_SAMPLES_ANGLE:
1629        {
1630            if (getMaxSupportedSamples() != 0)
1631            {
1632                *type = GL_INT;
1633                *numParams = 1;
1634            }
1635            else
1636            {
1637                return false;
1638            }
1639        }
1640        break;
1641      case GL_MAX_VIEWPORT_DIMS:
1642        {
1643            *type = GL_INT;
1644            *numParams = 2;
1645        }
1646        break;
1647      case GL_VIEWPORT:
1648      case GL_SCISSOR_BOX:
1649        {
1650            *type = GL_INT;
1651            *numParams = 4;
1652        }
1653        break;
1654      case GL_SHADER_COMPILER:
1655      case GL_SAMPLE_COVERAGE_INVERT:
1656      case GL_DEPTH_WRITEMASK:
1657      case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1658      case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1659      case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1660      case GL_SAMPLE_COVERAGE:
1661      case GL_SCISSOR_TEST:
1662      case GL_STENCIL_TEST:
1663      case GL_DEPTH_TEST:
1664      case GL_BLEND:
1665      case GL_DITHER:
1666      case GL_CONTEXT_ROBUST_ACCESS_EXT:
1667        {
1668            *type = GL_BOOL;
1669            *numParams = 1;
1670        }
1671        break;
1672      case GL_COLOR_WRITEMASK:
1673        {
1674            *type = GL_BOOL;
1675            *numParams = 4;
1676        }
1677        break;
1678      case GL_POLYGON_OFFSET_FACTOR:
1679      case GL_POLYGON_OFFSET_UNITS:
1680      case GL_SAMPLE_COVERAGE_VALUE:
1681      case GL_DEPTH_CLEAR_VALUE:
1682      case GL_LINE_WIDTH:
1683        {
1684            *type = GL_FLOAT;
1685            *numParams = 1;
1686        }
1687        break;
1688      case GL_ALIASED_LINE_WIDTH_RANGE:
1689      case GL_ALIASED_POINT_SIZE_RANGE:
1690      case GL_DEPTH_RANGE:
1691        {
1692            *type = GL_FLOAT;
1693            *numParams = 2;
1694        }
1695        break;
1696      case GL_COLOR_CLEAR_VALUE:
1697      case GL_BLEND_COLOR:
1698        {
1699            *type = GL_FLOAT;
1700            *numParams = 4;
1701        }
1702        break;
1703      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1704        if (!supportsTextureFilterAnisotropy())
1705        {
1706            return false;
1707        }
1708        *type = GL_FLOAT;
1709        *numParams = 1;
1710        break;
1711      default:
1712        return false;
1713    }
1714
1715    return true;
1716}
1717
1718// Applies the render target surface, depth stencil surface, viewport rectangle and
1719// scissor rectangle to the renderer
1720bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
1721{
1722    Framebuffer *framebufferObject = getDrawFramebuffer();
1723
1724    if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
1725    {
1726        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1727    }
1728
1729    mRenderer->applyRenderTarget(framebufferObject);
1730
1731    if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
1732                                ignoreViewport))
1733    {
1734        return false;
1735    }
1736
1737    mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
1738
1739    return true;
1740}
1741
1742// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
1743void Context::applyState(GLenum drawMode)
1744{
1745    Framebuffer *framebufferObject = getDrawFramebuffer();
1746    int samples = framebufferObject->getSamples();
1747
1748    mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
1749    mState.rasterizer.multiSample = (samples != 0);
1750    mRenderer->setRasterizerState(mState.rasterizer);
1751
1752    unsigned int mask = 0;
1753    if (mState.sampleCoverage)
1754    {
1755        if (mState.sampleCoverageValue != 0)
1756        {
1757
1758            float threshold = 0.5f;
1759
1760            for (int i = 0; i < samples; ++i)
1761            {
1762                mask <<= 1;
1763
1764                if ((i + 1) * mState.sampleCoverageValue >= threshold)
1765                {
1766                    threshold += 1.0f;
1767                    mask |= 1;
1768                }
1769            }
1770        }
1771
1772        if (mState.sampleCoverageInvert)
1773        {
1774            mask = ~mask;
1775        }
1776    }
1777    else
1778    {
1779        mask = 0xFFFFFFFF;
1780    }
1781    mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
1782
1783    mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
1784                                    mState.rasterizer.frontFace == GL_CCW);
1785}
1786
1787// Applies the shaders and shader constants to the Direct3D 9 device
1788void Context::applyShaders()
1789{
1790    ProgramBinary *programBinary = getCurrentProgramBinary();
1791
1792    mRenderer->applyShaders(programBinary);
1793
1794    programBinary->applyUniforms();
1795}
1796
1797// Applies the textures and sampler states to the Direct3D 9 device
1798void Context::applyTextures()
1799{
1800    applyTextures(SAMPLER_PIXEL);
1801
1802    if (mSupportsVertexTexture)
1803    {
1804        applyTextures(SAMPLER_VERTEX);
1805    }
1806}
1807
1808// For each Direct3D 9 sampler of either the pixel or vertex stage,
1809// looks up the corresponding OpenGL texture image unit and texture type,
1810// and sets the texture and its addressing/filtering state (or NULL when inactive).
1811void Context::applyTextures(SamplerType type)
1812{
1813    ProgramBinary *programBinary = getCurrentProgramBinary();
1814
1815    // Range of Direct3D samplers of given sampler type
1816    int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
1817    int samplerRange = programBinary->getUsedSamplerRange(type);
1818
1819    for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
1820    {
1821        int textureUnit = programBinary->getSamplerMapping(type, samplerIndex);   // OpenGL texture image unit index
1822
1823        if (textureUnit != -1)
1824        {
1825            TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
1826            Texture *texture = getSamplerTexture(textureUnit, textureType);
1827
1828            if (texture->isSamplerComplete())
1829            {
1830                SamplerState samplerState;
1831                texture->getSamplerState(&samplerState);
1832                mRenderer->setSamplerState(type, samplerIndex, samplerState);
1833
1834                mRenderer->setTexture(type, samplerIndex, texture);
1835
1836                texture->resetDirty();
1837            }
1838            else
1839            {
1840                mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
1841            }
1842        }
1843        else
1844        {
1845            mRenderer->setTexture(type, samplerIndex, NULL);
1846        }
1847    }
1848
1849    for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
1850    {
1851        mRenderer->setTexture(type, samplerIndex, NULL);
1852    }
1853}
1854
1855void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1856                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
1857{
1858    Framebuffer *framebuffer = getReadFramebuffer();
1859
1860    if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1861    {
1862        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
1863    }
1864
1865    if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
1866    {
1867        return gl::error(GL_INVALID_OPERATION);
1868    }
1869
1870    GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
1871    // sized query sanity check
1872    if (bufSize)
1873    {
1874        int requiredSize = outputPitch * height;
1875        if (requiredSize > *bufSize)
1876        {
1877            return gl::error(GL_INVALID_OPERATION);
1878        }
1879    }
1880
1881    mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
1882}
1883
1884void Context::clear(GLbitfield mask)
1885{
1886    Framebuffer *framebufferObject = getDrawFramebuffer();
1887
1888    if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
1889    {
1890        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
1891    }
1892
1893    DWORD flags = 0;
1894    GLbitfield finalMask = 0;
1895
1896    if (mask & GL_COLOR_BUFFER_BIT)
1897    {
1898        mask &= ~GL_COLOR_BUFFER_BIT;
1899
1900        if (framebufferObject->hasEnabledColorAttachment())
1901        {
1902            finalMask |= GL_COLOR_BUFFER_BIT;
1903        }
1904    }
1905
1906    if (mask & GL_DEPTH_BUFFER_BIT)
1907    {
1908        mask &= ~GL_DEPTH_BUFFER_BIT;
1909        if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
1910        {
1911            finalMask |= GL_DEPTH_BUFFER_BIT;
1912        }
1913    }
1914
1915    if (mask & GL_STENCIL_BUFFER_BIT)
1916    {
1917        mask &= ~GL_STENCIL_BUFFER_BIT;
1918        if (framebufferObject->getStencilbufferType() != GL_NONE)
1919        {
1920            rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
1921            if (!depthStencil)
1922            {
1923                ERR("Depth stencil pointer unexpectedly null.");
1924                return;
1925            }
1926
1927            if (GetStencilSize(depthStencil->getActualFormat()) > 0)
1928            {
1929                finalMask |= GL_STENCIL_BUFFER_BIT;
1930            }
1931        }
1932    }
1933
1934    if (mask != 0)
1935    {
1936        return gl::error(GL_INVALID_VALUE);
1937    }
1938
1939    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
1940    {
1941        return;
1942    }
1943
1944    ClearParameters clearParams;
1945    clearParams.mask = finalMask;
1946    clearParams.colorClearValue = mState.colorClearValue;
1947    clearParams.colorMaskRed = mState.blend.colorMaskRed;
1948    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
1949    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
1950    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
1951    clearParams.depthClearValue = mState.depthClearValue;
1952    clearParams.stencilClearValue = mState.stencilClearValue;
1953    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
1954
1955    mRenderer->clear(clearParams, framebufferObject);
1956}
1957
1958void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
1959{
1960    if (!mState.currentProgram)
1961    {
1962        return gl::error(GL_INVALID_OPERATION);
1963    }
1964
1965    if (!mRenderer->applyPrimitiveType(mode, count))
1966    {
1967        return;
1968    }
1969
1970    if (!applyRenderTarget(mode, false))
1971    {
1972        return;
1973    }
1974
1975    applyState(mode);
1976
1977    ProgramBinary *programBinary = getCurrentProgramBinary();
1978
1979    GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
1980    if (err != GL_NO_ERROR)
1981    {
1982        return gl::error(err);
1983    }
1984
1985    applyShaders();
1986    applyTextures();
1987
1988    if (!programBinary->validateSamplers(NULL))
1989    {
1990        return gl::error(GL_INVALID_OPERATION);
1991    }
1992
1993    if (!skipDraw(mode))
1994    {
1995        mRenderer->drawArrays(mode, count, instances);
1996    }
1997}
1998
1999void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
2000{
2001    if (!mState.currentProgram)
2002    {
2003        return gl::error(GL_INVALID_OPERATION);
2004    }
2005
2006    if (!indices && !mState.elementArrayBuffer)
2007    {
2008        return gl::error(GL_INVALID_OPERATION);
2009    }
2010
2011    if (!mRenderer->applyPrimitiveType(mode, count))
2012    {
2013        return;
2014    }
2015
2016    if (!applyRenderTarget(mode, false))
2017    {
2018        return;
2019    }
2020
2021    applyState(mode);
2022
2023    rx::TranslatedIndexData indexInfo;
2024    GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
2025    if (err != GL_NO_ERROR)
2026    {
2027        return gl::error(err);
2028    }
2029
2030    ProgramBinary *programBinary = getCurrentProgramBinary();
2031
2032    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2033    err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
2034    if (err != GL_NO_ERROR)
2035    {
2036        return gl::error(err);
2037    }
2038
2039    applyShaders();
2040    applyTextures();
2041
2042    if (!programBinary->validateSamplers(NULL))
2043    {
2044        return gl::error(GL_INVALID_OPERATION);
2045    }
2046
2047    if (!skipDraw(mode))
2048    {
2049        mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
2050    }
2051}
2052
2053// Implements glFlush when block is false, glFinish when block is true
2054void Context::sync(bool block)
2055{
2056    mRenderer->sync(block);
2057}
2058
2059void Context::recordInvalidEnum()
2060{
2061    mInvalidEnum = true;
2062}
2063
2064void Context::recordInvalidValue()
2065{
2066    mInvalidValue = true;
2067}
2068
2069void Context::recordInvalidOperation()
2070{
2071    mInvalidOperation = true;
2072}
2073
2074void Context::recordOutOfMemory()
2075{
2076    mOutOfMemory = true;
2077}
2078
2079void Context::recordInvalidFramebufferOperation()
2080{
2081    mInvalidFramebufferOperation = true;
2082}
2083
2084// Get one of the recorded errors and clear its flag, if any.
2085// [OpenGL ES 2.0.24] section 2.5 page 13.
2086GLenum Context::getError()
2087{
2088    if (mInvalidEnum)
2089    {
2090        mInvalidEnum = false;
2091
2092        return GL_INVALID_ENUM;
2093    }
2094
2095    if (mInvalidValue)
2096    {
2097        mInvalidValue = false;
2098
2099        return GL_INVALID_VALUE;
2100    }
2101
2102    if (mInvalidOperation)
2103    {
2104        mInvalidOperation = false;
2105
2106        return GL_INVALID_OPERATION;
2107    }
2108
2109    if (mOutOfMemory)
2110    {
2111        mOutOfMemory = false;
2112
2113        return GL_OUT_OF_MEMORY;
2114    }
2115
2116    if (mInvalidFramebufferOperation)
2117    {
2118        mInvalidFramebufferOperation = false;
2119
2120        return GL_INVALID_FRAMEBUFFER_OPERATION;
2121    }
2122
2123    return GL_NO_ERROR;
2124}
2125
2126GLenum Context::getResetStatus()
2127{
2128    if (mResetStatus == GL_NO_ERROR && !mContextLost)
2129    {
2130        // mResetStatus will be set by the markContextLost callback
2131        // in the case a notification is sent
2132        mRenderer->testDeviceLost(true);
2133    }
2134
2135    GLenum status = mResetStatus;
2136
2137    if (mResetStatus != GL_NO_ERROR)
2138    {
2139        ASSERT(mContextLost);
2140
2141        if (mRenderer->testDeviceResettable())
2142        {
2143            mResetStatus = GL_NO_ERROR;
2144        }
2145    }
2146
2147    return status;
2148}
2149
2150bool Context::isResetNotificationEnabled()
2151{
2152    return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
2153}
2154
2155int Context::getMajorShaderModel() const
2156{
2157    return mMajorShaderModel;
2158}
2159
2160float Context::getMaximumPointSize() const
2161{
2162    return mMaximumPointSize;
2163}
2164
2165unsigned int Context::getMaximumCombinedTextureImageUnits() const
2166{
2167    return mRenderer->getMaxCombinedTextureImageUnits();
2168}
2169
2170int Context::getMaxSupportedSamples() const
2171{
2172    return mRenderer->getMaxSupportedSamples();
2173}
2174
2175unsigned int Context::getMaximumRenderTargets() const
2176{
2177    return mRenderer->getMaxRenderTargets();
2178}
2179
2180bool Context::supportsEventQueries() const
2181{
2182    return mSupportsEventQueries;
2183}
2184
2185bool Context::supportsOcclusionQueries() const
2186{
2187    return mSupportsOcclusionQueries;
2188}
2189
2190bool Context::supportsBGRATextures() const
2191{
2192    return mSupportsBGRATextures;
2193}
2194
2195bool Context::supportsDXT1Textures() const
2196{
2197    return mSupportsDXT1Textures;
2198}
2199
2200bool Context::supportsDXT3Textures() const
2201{
2202    return mSupportsDXT3Textures;
2203}
2204
2205bool Context::supportsDXT5Textures() const
2206{
2207    return mSupportsDXT5Textures;
2208}
2209
2210bool Context::supportsFloat32Textures() const
2211{
2212    return mSupportsFloat32Textures;
2213}
2214
2215bool Context::supportsFloat32LinearFilter() const
2216{
2217    return mSupportsFloat32LinearFilter;
2218}
2219
2220bool Context::supportsFloat32RenderableTextures() const
2221{
2222    return mSupportsFloat32RenderableTextures;
2223}
2224
2225bool Context::supportsFloat16Textures() const
2226{
2227    return mSupportsFloat16Textures;
2228}
2229
2230bool Context::supportsFloat16LinearFilter() const
2231{
2232    return mSupportsFloat16LinearFilter;
2233}
2234
2235bool Context::supportsFloat16RenderableTextures() const
2236{
2237    return mSupportsFloat16RenderableTextures;
2238}
2239
2240int Context::getMaximumRenderbufferDimension() const
2241{
2242    return mMaxRenderbufferDimension;
2243}
2244
2245int Context::getMaximumTextureDimension() const
2246{
2247    return mMaxTextureDimension;
2248}
2249
2250int Context::getMaximumCubeTextureDimension() const
2251{
2252    return mMaxCubeTextureDimension;
2253}
2254
2255int Context::getMaximumTextureLevel() const
2256{
2257    return mMaxTextureLevel;
2258}
2259
2260bool Context::supportsLuminanceTextures() const
2261{
2262    return mSupportsLuminanceTextures;
2263}
2264
2265bool Context::supportsLuminanceAlphaTextures() const
2266{
2267    return mSupportsLuminanceAlphaTextures;
2268}
2269
2270bool Context::supportsDepthTextures() const
2271{
2272    return mSupportsDepthTextures;
2273}
2274
2275bool Context::supports32bitIndices() const
2276{
2277    return mSupports32bitIndices;
2278}
2279
2280bool Context::supportsNonPower2Texture() const
2281{
2282    return mSupportsNonPower2Texture;
2283}
2284
2285bool Context::supportsInstancing() const
2286{
2287    return mSupportsInstancing;
2288}
2289
2290bool Context::supportsTextureFilterAnisotropy() const
2291{
2292    return mSupportsTextureFilterAnisotropy;
2293}
2294
2295float Context::getTextureMaxAnisotropy() const
2296{
2297    return mMaxTextureAnisotropy;
2298}
2299
2300bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
2301{
2302    Framebuffer *framebuffer = getReadFramebuffer();
2303    if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2304    {
2305        return gl::error(GL_INVALID_OPERATION, false);
2306    }
2307
2308    Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
2309    if (!renderbuffer)
2310    {
2311        return gl::error(GL_INVALID_OPERATION, false);
2312    }
2313
2314    *format = gl::ExtractFormat(renderbuffer->getActualFormat());
2315    *type = gl::ExtractType(renderbuffer->getActualFormat());
2316
2317    return true;
2318}
2319
2320void Context::detachBuffer(GLuint buffer)
2321{
2322    // [OpenGL ES 2.0.24] section 2.9 page 22:
2323    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2324    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2325
2326    if (mState.arrayBuffer.id() == buffer)
2327    {
2328        mState.arrayBuffer.set(NULL);
2329    }
2330
2331    if (mState.elementArrayBuffer.id() == buffer)
2332    {
2333        mState.elementArrayBuffer.set(NULL);
2334    }
2335
2336    for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2337    {
2338        if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
2339        {
2340            mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
2341        }
2342    }
2343}
2344
2345void Context::detachTexture(GLuint texture)
2346{
2347    // [OpenGL ES 2.0.24] section 3.8 page 84:
2348    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2349    // rebound to texture object zero
2350
2351    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2352    {
2353        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2354        {
2355            if (mState.samplerTexture[type][sampler].id() == texture)
2356            {
2357                mState.samplerTexture[type][sampler].set(NULL);
2358            }
2359        }
2360    }
2361
2362    // [OpenGL ES 2.0.24] section 4.4 page 112:
2363    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2364    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2365    // image was attached in the currently bound framebuffer.
2366
2367    Framebuffer *readFramebuffer = getReadFramebuffer();
2368    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2369
2370    if (readFramebuffer)
2371    {
2372        readFramebuffer->detachTexture(texture);
2373    }
2374
2375    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
2376    {
2377        drawFramebuffer->detachTexture(texture);
2378    }
2379}
2380
2381void Context::detachFramebuffer(GLuint framebuffer)
2382{
2383    // [OpenGL ES 2.0.24] section 4.4 page 107:
2384    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2385    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2386
2387    if (mState.readFramebuffer == framebuffer)
2388    {
2389        bindReadFramebuffer(0);
2390    }
2391
2392    if (mState.drawFramebuffer == framebuffer)
2393    {
2394        bindDrawFramebuffer(0);
2395    }
2396}
2397
2398void Context::detachRenderbuffer(GLuint renderbuffer)
2399{
2400    // [OpenGL ES 2.0.24] section 4.4 page 109:
2401    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2402    // had been executed with the target RENDERBUFFER and name of zero.
2403
2404    if (mState.renderbuffer.id() == renderbuffer)
2405    {
2406        bindRenderbuffer(0);
2407    }
2408
2409    // [OpenGL ES 2.0.24] section 4.4 page 111:
2410    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2411    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2412    // point to which this image was attached in the currently bound framebuffer.
2413
2414    Framebuffer *readFramebuffer = getReadFramebuffer();
2415    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2416
2417    if (readFramebuffer)
2418    {
2419        readFramebuffer->detachRenderbuffer(renderbuffer);
2420    }
2421
2422    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
2423    {
2424        drawFramebuffer->detachRenderbuffer(renderbuffer);
2425    }
2426}
2427
2428Texture *Context::getIncompleteTexture(TextureType type)
2429{
2430    Texture *t = mIncompleteTextures[type].get();
2431
2432    if (t == NULL)
2433    {
2434        static const GLubyte color[] = { 0, 0, 0, 255 };
2435
2436        switch (type)
2437        {
2438          default:
2439            UNREACHABLE();
2440            // default falls through to TEXTURE_2D
2441
2442          case TEXTURE_2D:
2443            {
2444                Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
2445                incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2446                t = incomplete2d;
2447            }
2448            break;
2449
2450          case TEXTURE_CUBE:
2451            {
2452              TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
2453
2454              incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2455              incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2456              incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2457              incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2458              incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2459              incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
2460
2461              t = incompleteCube;
2462            }
2463            break;
2464        }
2465
2466        mIncompleteTextures[type].set(t);
2467    }
2468
2469    return t;
2470}
2471
2472bool Context::skipDraw(GLenum drawMode)
2473{
2474    if (drawMode == GL_POINTS)
2475    {
2476        // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
2477        // which affects varying interpolation. Since the value of gl_PointSize is
2478        // undefined when not written, just skip drawing to avoid unexpected results.
2479        if (!getCurrentProgramBinary()->usesPointSize())
2480        {
2481            // This is stictly speaking not an error, but developers should be
2482            // notified of risking undefined behavior.
2483            ERR("Point rendering without writing to gl_PointSize.");
2484
2485            return true;
2486        }
2487    }
2488    else if (IsTriangleMode(drawMode))
2489    {
2490        if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
2491        {
2492            return true;
2493        }
2494    }
2495
2496    return false;
2497}
2498
2499void Context::setVertexAttrib(GLuint index, const GLfloat *values)
2500{
2501    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
2502
2503    mState.vertexAttribute[index].mCurrentValue[0] = values[0];
2504    mState.vertexAttribute[index].mCurrentValue[1] = values[1];
2505    mState.vertexAttribute[index].mCurrentValue[2] = values[2];
2506    mState.vertexAttribute[index].mCurrentValue[3] = values[3];
2507}
2508
2509void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
2510{
2511    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
2512
2513    mState.vertexAttribute[index].mDivisor = divisor;
2514}
2515
2516// keep list sorted in following order
2517// OES extensions
2518// EXT extensions
2519// Vendor extensions
2520void Context::initExtensionString()
2521{
2522    std::string extensionString = "";
2523
2524    // OES extensions
2525    if (supports32bitIndices())
2526    {
2527        extensionString += "GL_OES_element_index_uint ";
2528    }
2529
2530    extensionString += "GL_OES_packed_depth_stencil ";
2531    extensionString += "GL_OES_get_program_binary ";
2532    extensionString += "GL_OES_rgb8_rgba8 ";
2533    if (mRenderer->getDerivativeInstructionSupport())
2534    {
2535        extensionString += "GL_OES_standard_derivatives ";
2536    }
2537
2538    if (supportsFloat16Textures())
2539    {
2540        extensionString += "GL_OES_texture_half_float ";
2541    }
2542    if (supportsFloat16LinearFilter())
2543    {
2544        extensionString += "GL_OES_texture_half_float_linear ";
2545    }
2546    if (supportsFloat32Textures())
2547    {
2548        extensionString += "GL_OES_texture_float ";
2549    }
2550    if (supportsFloat32LinearFilter())
2551    {
2552        extensionString += "GL_OES_texture_float_linear ";
2553    }
2554
2555    if (supportsNonPower2Texture())
2556    {
2557        extensionString += "GL_OES_texture_npot ";
2558    }
2559
2560    // Multi-vendor (EXT) extensions
2561    if (supportsOcclusionQueries())
2562    {
2563        extensionString += "GL_EXT_occlusion_query_boolean ";
2564    }
2565
2566    extensionString += "GL_EXT_read_format_bgra ";
2567    extensionString += "GL_EXT_robustness ";
2568
2569    if (supportsDXT1Textures())
2570    {
2571        extensionString += "GL_EXT_texture_compression_dxt1 ";
2572    }
2573
2574    if (supportsTextureFilterAnisotropy())
2575    {
2576        extensionString += "GL_EXT_texture_filter_anisotropic ";
2577    }
2578
2579    if (supportsBGRATextures())
2580    {
2581        extensionString += "GL_EXT_texture_format_BGRA8888 ";
2582    }
2583
2584    if (mRenderer->getMaxRenderTargets() > 1)
2585    {
2586        extensionString += "GL_EXT_draw_buffers ";
2587    }
2588
2589    extensionString += "GL_EXT_texture_storage ";
2590    extensionString += "GL_EXT_frag_depth ";
2591
2592    // ANGLE-specific extensions
2593    if (supportsDepthTextures())
2594    {
2595        extensionString += "GL_ANGLE_depth_texture ";
2596    }
2597
2598    extensionString += "GL_ANGLE_framebuffer_blit ";
2599    if (getMaxSupportedSamples() != 0)
2600    {
2601        extensionString += "GL_ANGLE_framebuffer_multisample ";
2602    }
2603
2604    if (supportsInstancing())
2605    {
2606        extensionString += "GL_ANGLE_instanced_arrays ";
2607    }
2608
2609    extensionString += "GL_ANGLE_pack_reverse_row_order ";
2610
2611    if (supportsDXT3Textures())
2612    {
2613        extensionString += "GL_ANGLE_texture_compression_dxt3 ";
2614    }
2615    if (supportsDXT5Textures())
2616    {
2617        extensionString += "GL_ANGLE_texture_compression_dxt5 ";
2618    }
2619
2620    extensionString += "GL_ANGLE_texture_usage ";
2621    extensionString += "GL_ANGLE_translated_shader_source ";
2622
2623    // Other vendor-specific extensions
2624    if (supportsEventQueries())
2625    {
2626        extensionString += "GL_NV_fence ";
2627    }
2628
2629    std::string::size_type end = extensionString.find_last_not_of(' ');
2630    if (end != std::string::npos)
2631    {
2632        extensionString.resize(end+1);
2633    }
2634
2635    mExtensionString = makeStaticString(extensionString);
2636}
2637
2638const char *Context::getExtensionString() const
2639{
2640    return mExtensionString;
2641}
2642
2643void Context::initRendererString()
2644{
2645    std::ostringstream rendererString;
2646    rendererString << "ANGLE (";
2647    rendererString << mRenderer->getRendererDescription();
2648    rendererString << ")";
2649
2650    mRendererString = makeStaticString(rendererString.str());
2651}
2652
2653const char *Context::getRendererString() const
2654{
2655    return mRendererString;
2656}
2657
2658void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2659                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2660                              GLbitfield mask)
2661{
2662    Framebuffer *readFramebuffer = getReadFramebuffer();
2663    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2664
2665    if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
2666        !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2667    {
2668        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
2669    }
2670
2671    if (drawFramebuffer->getSamples() != 0)
2672    {
2673        return gl::error(GL_INVALID_OPERATION);
2674    }
2675
2676    Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
2677    Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
2678
2679    if (drawColorBuffer == NULL)
2680    {
2681        ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
2682        return gl::error(GL_INVALID_OPERATION);
2683    }
2684
2685    int readBufferWidth = readColorBuffer->getWidth();
2686    int readBufferHeight = readColorBuffer->getHeight();
2687    int drawBufferWidth = drawColorBuffer->getWidth();
2688    int drawBufferHeight = drawColorBuffer->getHeight();
2689
2690    Rectangle sourceRect;
2691    Rectangle destRect;
2692
2693    if (srcX0 < srcX1)
2694    {
2695        sourceRect.x = srcX0;
2696        destRect.x = dstX0;
2697        sourceRect.width = srcX1 - srcX0;
2698        destRect.width = dstX1 - dstX0;
2699    }
2700    else
2701    {
2702        sourceRect.x = srcX1;
2703        destRect.x = dstX1;
2704        sourceRect.width = srcX0 - srcX1;
2705        destRect.width = dstX0 - dstX1;
2706    }
2707
2708    if (srcY0 < srcY1)
2709    {
2710        sourceRect.height = srcY1 - srcY0;
2711        destRect.height = dstY1 - dstY0;
2712        sourceRect.y = srcY0;
2713        destRect.y = dstY0;
2714    }
2715    else
2716    {
2717        sourceRect.height = srcY0 - srcY1;
2718        destRect.height = dstY0 - srcY1;
2719        sourceRect.y = srcY1;
2720        destRect.y = dstY1;
2721    }
2722
2723    Rectangle sourceScissoredRect = sourceRect;
2724    Rectangle destScissoredRect = destRect;
2725
2726    if (mState.scissorTest)
2727    {
2728        // Only write to parts of the destination framebuffer which pass the scissor test.
2729        if (destRect.x < mState.scissor.x)
2730        {
2731            int xDiff = mState.scissor.x - destRect.x;
2732            destScissoredRect.x = mState.scissor.x;
2733            destScissoredRect.width -= xDiff;
2734            sourceScissoredRect.x += xDiff;
2735            sourceScissoredRect.width -= xDiff;
2736
2737        }
2738
2739        if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
2740        {
2741            int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
2742            destScissoredRect.width -= xDiff;
2743            sourceScissoredRect.width -= xDiff;
2744        }
2745
2746        if (destRect.y < mState.scissor.y)
2747        {
2748            int yDiff = mState.scissor.y - destRect.y;
2749            destScissoredRect.y = mState.scissor.y;
2750            destScissoredRect.height -= yDiff;
2751            sourceScissoredRect.y += yDiff;
2752            sourceScissoredRect.height -= yDiff;
2753        }
2754
2755        if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
2756        {
2757            int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
2758            destScissoredRect.height  -= yDiff;
2759            sourceScissoredRect.height -= yDiff;
2760        }
2761    }
2762
2763    bool blitRenderTarget = false;
2764    bool blitDepthStencil = false;
2765
2766    Rectangle sourceTrimmedRect = sourceScissoredRect;
2767    Rectangle destTrimmedRect = destScissoredRect;
2768
2769    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2770    // the actual draw and read surfaces.
2771    if (sourceTrimmedRect.x < 0)
2772    {
2773        int xDiff = 0 - sourceTrimmedRect.x;
2774        sourceTrimmedRect.x = 0;
2775        sourceTrimmedRect.width -= xDiff;
2776        destTrimmedRect.x += xDiff;
2777        destTrimmedRect.width -= xDiff;
2778    }
2779
2780    if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
2781    {
2782        int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
2783        sourceTrimmedRect.width -= xDiff;
2784        destTrimmedRect.width -= xDiff;
2785    }
2786
2787    if (sourceTrimmedRect.y < 0)
2788    {
2789        int yDiff = 0 - sourceTrimmedRect.y;
2790        sourceTrimmedRect.y = 0;
2791        sourceTrimmedRect.height -= yDiff;
2792        destTrimmedRect.y += yDiff;
2793        destTrimmedRect.height -= yDiff;
2794    }
2795
2796    if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
2797    {
2798        int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
2799        sourceTrimmedRect.height -= yDiff;
2800        destTrimmedRect.height -= yDiff;
2801    }
2802
2803    if (destTrimmedRect.x < 0)
2804    {
2805        int xDiff = 0 - destTrimmedRect.x;
2806        destTrimmedRect.x = 0;
2807        destTrimmedRect.width -= xDiff;
2808        sourceTrimmedRect.x += xDiff;
2809        sourceTrimmedRect.width -= xDiff;
2810    }
2811
2812    if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
2813    {
2814        int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
2815        destTrimmedRect.width -= xDiff;
2816        sourceTrimmedRect.width -= xDiff;
2817    }
2818
2819    if (destTrimmedRect.y < 0)
2820    {
2821        int yDiff = 0 - destTrimmedRect.y;
2822        destTrimmedRect.y = 0;
2823        destTrimmedRect.height -= yDiff;
2824        sourceTrimmedRect.y += yDiff;
2825        sourceTrimmedRect.height -= yDiff;
2826    }
2827
2828    if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
2829    {
2830        int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
2831        destTrimmedRect.height -= yDiff;
2832        sourceTrimmedRect.height -= yDiff;
2833    }
2834
2835    bool partialBufferCopy = false;
2836    if (sourceTrimmedRect.height < readBufferHeight ||
2837        sourceTrimmedRect.width < readBufferWidth ||
2838        destTrimmedRect.height < drawBufferHeight ||
2839        destTrimmedRect.width < drawBufferWidth ||
2840        sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
2841    {
2842        partialBufferCopy = true;
2843    }
2844
2845    if (mask & GL_COLOR_BUFFER_BIT)
2846    {
2847        const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
2848        const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
2849        bool validDrawType = true;
2850        bool validDrawFormat = true;
2851
2852        for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
2853        {
2854            if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
2855            {
2856                if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
2857                    drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
2858                {
2859                    validDrawType = false;
2860                }
2861
2862                if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
2863                {
2864                    validDrawFormat = false;
2865                }
2866            }
2867        }
2868
2869        if (!validReadType || !validDrawType || !validDrawFormat)
2870        {
2871            ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2872            return gl::error(GL_INVALID_OPERATION);
2873        }
2874
2875        if (partialBufferCopy && readFramebuffer->getSamples() != 0)
2876        {
2877            return gl::error(GL_INVALID_OPERATION);
2878        }
2879
2880        blitRenderTarget = true;
2881
2882    }
2883
2884    if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2885    {
2886        Renderbuffer *readDSBuffer = NULL;
2887        Renderbuffer *drawDSBuffer = NULL;
2888
2889        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2890        // both a depth and stencil buffer, it will be the same buffer.
2891
2892        if (mask & GL_DEPTH_BUFFER_BIT)
2893        {
2894            if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2895            {
2896                if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2897                    readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
2898                {
2899                    return gl::error(GL_INVALID_OPERATION);
2900                }
2901
2902                blitDepthStencil = true;
2903                readDSBuffer = readFramebuffer->getDepthbuffer();
2904                drawDSBuffer = drawFramebuffer->getDepthbuffer();
2905            }
2906        }
2907
2908        if (mask & GL_STENCIL_BUFFER_BIT)
2909        {
2910            if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2911            {
2912                if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2913                    readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
2914                {
2915                    return gl::error(GL_INVALID_OPERATION);
2916                }
2917
2918                blitDepthStencil = true;
2919                readDSBuffer = readFramebuffer->getStencilbuffer();
2920                drawDSBuffer = drawFramebuffer->getStencilbuffer();
2921            }
2922        }
2923
2924        if (partialBufferCopy)
2925        {
2926            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2927            return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
2928        }
2929
2930        if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
2931            (readDSBuffer && readDSBuffer->getSamples() != 0))
2932        {
2933            return gl::error(GL_INVALID_OPERATION);
2934        }
2935    }
2936
2937    if (blitRenderTarget || blitDepthStencil)
2938    {
2939        mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
2940    }
2941}
2942
2943}
2944
2945extern "C"
2946{
2947gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
2948{
2949    return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
2950}
2951
2952void glDestroyContext(gl::Context *context)
2953{
2954    delete context;
2955
2956    if (context == gl::getContext())
2957    {
2958        gl::makeCurrent(NULL, NULL, NULL);
2959    }
2960}
2961
2962void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
2963{
2964    gl::makeCurrent(context, display, surface);
2965}
2966
2967gl::Context *glGetCurrentContext()
2968{
2969    return gl::getContext();
2970}
2971
2972}
2973