//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Context.cpp: Implements the gl::Context class, managing all GL state and performing
// rendering operations. It is the GLES2 specific implementation of EGLContext.

#include "Context.h"

#include <algorithm>

#include "main.h"
#include "libEGL/Display.h"
#include "Buffer.h"
#include "Shader.h"
#include "Program.h"
#include "Texture.h"
#include "FrameBuffer.h"
#include "RenderBuffer.h"
#include "mathutil.h"
#include "utilities.h"
#include "geometry/backend.h"
#include "geometry/VertexDataManager.h"
#include "geometry/IndexDataManager.h"
#include "geometry/dx9.h"

#undef near
#undef far

namespace gl
{
Context::Context(const egl::Config *config)
    : mConfig(config)
{
    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    depthClearValue = 1.0f;
    stencilClearValue = 0;

    cullFace = false;
    cullMode = GL_BACK;
    frontFace = GL_CCW;
    depthTest = false;
    depthFunc = GL_LESS;
    blend = false;
    sourceBlendRGB = GL_ONE;
    sourceBlendAlpha = GL_ONE;
    destBlendRGB = GL_ZERO;
    destBlendAlpha = GL_ZERO;
    blendEquationRGB = GL_FUNC_ADD;
    blendEquationAlpha = GL_FUNC_ADD;
    blendColor.red = 0;
    blendColor.green = 0;
    blendColor.blue = 0;
    blendColor.alpha = 0;
    stencilTest = false;
    stencilFunc = GL_ALWAYS;
    stencilRef = 0;
    stencilMask = -1;
    stencilWritemask = -1;
    stencilBackFunc = GL_ALWAYS;
    stencilBackRef = 0;
    stencilBackMask = - 1;
    stencilBackWritemask = -1;
    stencilFail = GL_KEEP;
    stencilPassDepthFail = GL_KEEP;
    stencilPassDepthPass = GL_KEEP;
    stencilBackFail = GL_KEEP;
    stencilBackPassDepthFail = GL_KEEP;
    stencilBackPassDepthPass = GL_KEEP;
    polygonOffsetFill = false;
    polygonOffsetFactor = 0.0f;
    polygonOffsetUnits = 0.0f;
    sampleAlphaToCoverage = false;
    sampleCoverage = false;
    sampleCoverageValue = 1.0f;
    sampleCoverageInvert = GL_FALSE;
    scissorTest = false;
    dither = true;
    generateMipmapHint = GL_DONT_CARE;

    lineWidth = 1.0f;

    viewportX = 0;
    viewportY = 0;
    viewportWidth = config->mDisplayMode.Width;
    viewportHeight = config->mDisplayMode.Height;
    zNear = 0.0f;
    zFar = 1.0f;

    scissorX = 0;
    scissorY = 0;
    scissorWidth = config->mDisplayMode.Width;
    scissorHeight = config->mDisplayMode.Height;

    colorMaskRed = true;
    colorMaskGreen = true;
    colorMaskBlue = true;
    colorMaskAlpha = true;
    depthMask = true;

    // [OpenGL ES 2.0.24] section 3.7 page 83:
    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
    // and cube map texture state vectors respectively associated with them.
    // In order that access to these initial textures not be lost, they are treated as texture
    // objects all of whose names are 0.

    mTexture2DZero = new Texture2D();
    mTextureCubeMapZero = new TextureCubeMap();

    mColorbufferZero = NULL;
    mDepthbufferZero = NULL;
    mStencilbufferZero = NULL;

    activeSampler = 0;
    arrayBuffer = 0;
    elementArrayBuffer = 0;
    bindTextureCubeMap(0);
    bindTexture2D(0);
    bindFramebuffer(0);
    bindRenderbuffer(0);

    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
    {
        for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
        {
            samplerTexture[type][sampler] = 0;
        }
    }

    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
    {
        mIncompleteTextures[type] = NULL;
    }

    currentProgram = 0;

    packAlignment = 4;
    unpackAlignment = 4;

    mBufferBackEnd = NULL;
    mVertexDataManager = NULL;
    mIndexDataManager = NULL;

    mInvalidEnum = false;
    mInvalidValue = false;
    mInvalidOperation = false;
    mOutOfMemory = false;
    mInvalidFramebufferOperation = false;

    mHasBeenCurrent = false;
}

Context::~Context()
{
    currentProgram = 0;

    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
    {
        delete mIncompleteTextures[type];
    }

    delete mTexture2DZero;
    delete mTextureCubeMapZero;

    delete mColorbufferZero;
    delete mDepthbufferZero;
    delete mStencilbufferZero;

    delete mBufferBackEnd;
    delete mVertexDataManager;
    delete mIndexDataManager;

    while (!mBufferMap.empty())
    {
        deleteBuffer(mBufferMap.begin()->first);
    }

    while (!mProgramMap.empty())
    {
        deleteProgram(mProgramMap.begin()->first);
    }

    while (!mShaderMap.empty())
    {
        deleteShader(mShaderMap.begin()->first);
    }

    while (!mFramebufferMap.empty())
    {
        deleteFramebuffer(mFramebufferMap.begin()->first);
    }

    while (!mRenderbufferMap.empty())
    {
        deleteRenderbuffer(mRenderbufferMap.begin()->first);
    }

    while (!mTextureMap.empty())
    {
        deleteTexture(mTextureMap.begin()->first);
    }
}

void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
    IDirect3DDevice9 *device = display->getDevice();

    if (!mBufferBackEnd)
    {
        mBufferBackEnd = new Dx9BackEnd(device);
        mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
        mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
    }

    // Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
    IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
    IDirect3DSurface9 *depthStencil = surface->getDepthStencil();

    Framebuffer *framebufferZero = new Framebuffer();
    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
    Depthbuffer *depthbufferZero = new Depthbuffer(depthStencil);
    Stencilbuffer *stencilbufferZero = new Stencilbuffer(depthStencil);

    setFramebufferZero(framebufferZero);
    setColorbufferZero(colorbufferZero);
    setDepthbufferZero(depthbufferZero);
    setStencilbufferZero(stencilbufferZero);

    framebufferZero->setColorbuffer(GL_RENDERBUFFER, 0);
    framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0);
    framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0);

    if(!mHasBeenCurrent)
    {
        viewportX = 0;
        viewportY = 0;
        viewportWidth = surface->getWidth();
        viewportHeight = surface->getHeight();

        scissorX = 0;
        scissorY = 0;
        scissorWidth = surface->getWidth();
        scissorHeight = surface->getHeight();

        mHasBeenCurrent = true;
    }

    defaultRenderTarget->Release();

    if (depthStencil)
    {
        depthStencil->Release();
    }

    D3DCAPS9 capabilities;
    device->GetDeviceCaps(&capabilities);
    
    if (capabilities.PixelShaderVersion == D3DPS_VERSION(3, 0))
    {
        mPsProfile = "ps_3_0";
        mVsProfile = "vs_3_0";
    }
    else  // egl::Display guarantees support for at least 2.0
    {
        mPsProfile = "ps_2_0";
        mVsProfile = "vs_2_0";
    }
}

void Context::setClearColor(float red, float green, float blue, float alpha)
{
    colorClearValue.red = red;
    colorClearValue.green = green;
    colorClearValue.blue = blue;
    colorClearValue.alpha = alpha;
}

void Context::setClearDepth(float depth)
{
    depthClearValue = depth;
}

void Context::setClearStencil(int stencil)
{
    stencilClearValue = stencil;
}

// Returns an unused buffer name
GLuint Context::createBuffer()
{
    unsigned int handle = 1;

    while (mBufferMap.find(handle) != mBufferMap.end())
    {
        handle++;
    }

    mBufferMap[handle] = NULL;

    return handle;
}

// Returns an unused shader/program name
GLuint Context::createShader(GLenum type)
{
    unsigned int handle = 1;

    while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end())   // Shared name space
    {
        handle++;
    }

    if (type == GL_VERTEX_SHADER)
    {
        mShaderMap[handle] = new VertexShader(handle);
    }
    else if (type == GL_FRAGMENT_SHADER)
    {
        mShaderMap[handle] = new FragmentShader(handle);
    }
    else UNREACHABLE();

    return handle;
}

// Returns an unused program/shader name
GLuint Context::createProgram()
{
    unsigned int handle = 1;

    while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end())   // Shared name space
    {
        handle++;
    }

    mProgramMap[handle] = new Program();

    return handle;
}

// Returns an unused texture name
GLuint Context::createTexture()
{
    unsigned int handle = 1;

    while (mTextureMap.find(handle) != mTextureMap.end())
    {
        handle++;
    }

    mTextureMap[handle] = NULL;

    return handle;
}

// Returns an unused framebuffer name
GLuint Context::createFramebuffer()
{
    unsigned int handle = 1;

    while (mFramebufferMap.find(handle) != mFramebufferMap.end())
    {
        handle++;
    }

    mFramebufferMap[handle] = NULL;

    return handle;
}

// Returns an unused renderbuffer name
GLuint Context::createRenderbuffer()
{
    unsigned int handle = 1;

    while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
    {
        handle++;
    }

    mRenderbufferMap[handle] = NULL;

    return handle;
}

void Context::deleteBuffer(GLuint buffer)
{
    BufferMap::iterator bufferObject = mBufferMap.find(buffer);

    if (bufferObject != mBufferMap.end())
    {
        detachBuffer(buffer);

        delete bufferObject->second;
        mBufferMap.erase(bufferObject);
    }
}

void Context::deleteShader(GLuint shader)
{
    ShaderMap::iterator shaderObject = mShaderMap.find(shader);

    if (shaderObject != mShaderMap.end())
    {
        if (!shaderObject->second->isAttached())
        {
            delete shaderObject->second;
            mShaderMap.erase(shaderObject);
        }
        else
        {
            shaderObject->second->flagForDeletion();
        }
    }
}

void Context::deleteProgram(GLuint program)
{
    ProgramMap::iterator programObject = mProgramMap.find(program);

    if (programObject != mProgramMap.end())
    {
        if (program != currentProgram)
        {
            delete programObject->second;
            mProgramMap.erase(programObject);
        }
        else
        {
            programObject->second->flagForDeletion();
        }
    }
}

void Context::deleteTexture(GLuint texture)
{
    TextureMap::iterator textureObject = mTextureMap.find(texture);

    if (textureObject != mTextureMap.end())
    {
        detachTexture(texture);

        if (texture != 0)
        {
            delete textureObject->second;
        }

        mTextureMap.erase(textureObject);
    }
}

void Context::deleteFramebuffer(GLuint framebuffer)
{
    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);

    if (framebufferObject != mFramebufferMap.end())
    {
        detachFramebuffer(framebuffer);

        delete framebufferObject->second;
        mFramebufferMap.erase(framebufferObject);
    }
}

void Context::deleteRenderbuffer(GLuint renderbuffer)
{
    RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);

    if (renderbufferObject != mRenderbufferMap.end())
    {
        detachRenderbuffer(renderbuffer);

        delete renderbufferObject->second;
        mRenderbufferMap.erase(renderbufferObject);
    }
}

void Context::bindArrayBuffer(unsigned int buffer)
{
    if (buffer != 0 && !getBuffer(buffer))
    {
        mBufferMap[buffer] = new Buffer(mBufferBackEnd);
    }

    arrayBuffer = buffer;
}

void Context::bindElementArrayBuffer(unsigned int buffer)
{
    if (buffer != 0 && !getBuffer(buffer))
    {
        mBufferMap[buffer] = new Buffer(mBufferBackEnd);
    }

    elementArrayBuffer = buffer;
}

void Context::bindTexture2D(GLuint texture)
{
    if (!getTexture(texture) && texture != 0)
    {
        mTextureMap[texture] = new Texture2D();
    }

    texture2D = texture;

    samplerTexture[SAMPLER_2D][activeSampler] = texture;
}

void Context::bindTextureCubeMap(GLuint texture)
{
    if (!getTexture(texture) && texture != 0)
    {
        mTextureMap[texture] = new TextureCubeMap();
    }

    textureCubeMap = texture;

    samplerTexture[SAMPLER_CUBE][activeSampler] = texture;
}

void Context::bindFramebuffer(GLuint framebuffer)
{
    if (!getFramebuffer(framebuffer))
    {
        mFramebufferMap[framebuffer] = new Framebuffer();
    }

    this->framebuffer = framebuffer;
}

void Context::bindRenderbuffer(GLuint renderbuffer)
{
    if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
    {
        mRenderbufferMap[renderbuffer] = new Renderbuffer();
    }

    this->renderbuffer = renderbuffer;
}

void Context::useProgram(GLuint program)
{
    Program *programObject = getCurrentProgram();

    if (programObject && programObject->isFlaggedForDeletion())
    {
        deleteProgram(currentProgram);
    }

    currentProgram = program;
}

void Context::setFramebufferZero(Framebuffer *buffer)
{
    delete mFramebufferMap[0];
    mFramebufferMap[0] = buffer;
}

void Context::setColorbufferZero(Colorbuffer *buffer)
{
    delete mColorbufferZero;
    mColorbufferZero = buffer;
}

void Context::setDepthbufferZero(Depthbuffer *buffer)
{
    delete mDepthbufferZero;
    mDepthbufferZero = buffer;
}

void Context::setStencilbufferZero(Stencilbuffer *buffer)
{
    delete mStencilbufferZero;
    mStencilbufferZero = buffer;
}

void Context::setRenderbuffer(Renderbuffer *buffer)
{
    delete mRenderbufferMap[renderbuffer];
    mRenderbufferMap[renderbuffer] = buffer;
}

Buffer *Context::getBuffer(unsigned int handle)
{
    BufferMap::iterator buffer = mBufferMap.find(handle);

    if (buffer == mBufferMap.end())
    {
        return NULL;
    }
    else
    {
        return buffer->second;
    }
}

Shader *Context::getShader(unsigned int handle)
{
    ShaderMap::iterator shader = mShaderMap.find(handle);

    if (shader == mShaderMap.end())
    {
        return NULL;
    }
    else
    {
        return shader->second;
    }
}

Program *Context::getProgram(unsigned int handle)
{
    ProgramMap::iterator program = mProgramMap.find(handle);

    if (program == mProgramMap.end())
    {
        return NULL;
    }
    else
    {
        return program->second;
    }
}

Texture *Context::getTexture(unsigned int handle)
{
    if (handle == 0) return NULL;

    TextureMap::iterator texture = mTextureMap.find(handle);

    if (texture == mTextureMap.end())
    {
        return NULL;
    }
    else
    {
        return texture->second;
    }
}

Framebuffer *Context::getFramebuffer(unsigned int handle)
{
    FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);

    if (framebuffer == mFramebufferMap.end())
    {
        return NULL;
    }
    else
    {
        return framebuffer->second;
    }
}

Renderbuffer *Context::getRenderbuffer(unsigned int handle)
{
    RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);

    if (renderbuffer == mRenderbufferMap.end())
    {
        return NULL;
    }
    else
    {
        return renderbuffer->second;
    }
}

Colorbuffer *Context::getColorbuffer(GLuint handle)
{
    if (handle != 0)
    {
        Renderbuffer *renderbuffer = getRenderbuffer(handle);

        if (renderbuffer && renderbuffer->isColorbuffer())
        {
            return static_cast<Colorbuffer*>(renderbuffer);
        }
    }
    else   // Special case: 0 refers to different initial render targets based on the attachment type
    {
        return mColorbufferZero;
    }

    return NULL;
}

Depthbuffer *Context::getDepthbuffer(GLuint handle)
{
    if (handle != 0)
    {
        Renderbuffer *renderbuffer = getRenderbuffer(handle);

        if (renderbuffer && renderbuffer->isDepthbuffer())
        {
            return static_cast<Depthbuffer*>(renderbuffer);
        }
    }
    else   // Special case: 0 refers to different initial render targets based on the attachment type
    {
        return mDepthbufferZero;
    }

    return NULL;
}

Stencilbuffer *Context::getStencilbuffer(GLuint handle)
{
    if (handle != 0)
    {
        Renderbuffer *renderbuffer = getRenderbuffer(handle);

        if (renderbuffer && renderbuffer->isStencilbuffer())
        {
            return static_cast<Stencilbuffer*>(renderbuffer);
        }
    }
    else
    {
        return mStencilbufferZero;
    }

    return NULL;
}

Buffer *Context::getArrayBuffer()
{
    return getBuffer(arrayBuffer);
}

Buffer *Context::getElementArrayBuffer()
{
    return getBuffer(elementArrayBuffer);
}

Program *Context::getCurrentProgram()
{
    return getProgram(currentProgram);
}

Texture2D *Context::getTexture2D()
{
    if (texture2D == 0)   // Special case: 0 refers to different initial textures based on the target
    {
        return mTexture2DZero;
    }

    return (Texture2D*)getTexture(texture2D);
}

TextureCubeMap *Context::getTextureCubeMap()
{
    if (textureCubeMap == 0)   // Special case: 0 refers to different initial textures based on the target
    {
        return mTextureCubeMapZero;
    }

    return (TextureCubeMap*)getTexture(textureCubeMap);
}

Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
{
    GLuint texid = samplerTexture[type][sampler];

    if (texid == 0)
    {
        switch (type)
        {
          default: UNREACHABLE();
          case SAMPLER_2D: return mTexture2DZero;
          case SAMPLER_CUBE: return mTextureCubeMapZero;
        }
    }

    return getTexture(texid);
}

Framebuffer *Context::getFramebuffer()
{
    return getFramebuffer(framebuffer);
}

bool Context::getBooleanv(GLenum pname, GLboolean *params)
{
    switch (pname)
    {
      case GL_SHADER_COMPILER:          *params = GL_TRUE;                  break;
      case GL_SAMPLE_COVERAGE_INVERT:   *params = sampleCoverageInvert;     break;
      case GL_DEPTH_WRITEMASK:          *params = depthMask;                break;
      case GL_COLOR_WRITEMASK:
        params[0] = colorMaskRed;
        params[1] = colorMaskGreen;
        params[2] = colorMaskBlue;
        params[3] = colorMaskAlpha;
        break;
      default:
        return false;
    }

    return true;
}

bool Context::getFloatv(GLenum pname, GLfloat *params)
{
    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
    // GetIntegerv as its native query function. As it would require conversion in any
    // case, this should make no difference to the calling application.
    switch (pname)
    {
      case GL_LINE_WIDTH:               *params = lineWidth;            break;
      case GL_SAMPLE_COVERAGE_VALUE:    *params = sampleCoverageValue;  break;
      case GL_DEPTH_CLEAR_VALUE:        *params = depthClearValue;      break;
      case GL_POLYGON_OFFSET_FACTOR:    *params = polygonOffsetFactor;  break;
      case GL_POLYGON_OFFSET_UNITS:     *params = polygonOffsetUnits;   break;
      case GL_ALIASED_LINE_WIDTH_RANGE:
        params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
        params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
        break;
      case GL_ALIASED_POINT_SIZE_RANGE:
        params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
        params[1] = gl::ALIASED_POINT_SIZE_RANGE_MAX;
        break;
      case GL_DEPTH_RANGE:
        params[0] = zNear;
        params[1] = zFar;
        break;
      case GL_COLOR_CLEAR_VALUE:
        params[0] = colorClearValue.red;
        params[1] = colorClearValue.green;
        params[2] = colorClearValue.blue;
        params[3] = colorClearValue.alpha;
        break;
      default:
        return false;
    }

    return true;
}

bool Context::getIntegerv(GLenum pname, GLint *params)
{
    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
    // GetIntegerv as its native query function. As it would require conversion in any
    // case, this should make no difference to the calling application. You may find it in 
    // Context::getFloatv.
    switch (pname)
    {
      case GL_MAX_VERTEX_ATTRIBS:               *params = gl::MAX_VERTEX_ATTRIBS;               break;
      case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = gl::MAX_VERTEX_UNIFORM_VECTORS;       break;
      case GL_MAX_VARYING_VECTORS:              *params = gl::MAX_VARYING_VECTORS;              break;
      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
      case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS;     break;
      case GL_MAX_RENDERBUFFER_SIZE:            *params = gl::MAX_RENDERBUFFER_SIZE;            break;
      case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                break;
      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = 0;                                break;
      case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */ break;
      case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */      break;
      case GL_ARRAY_BUFFER_BINDING:             *params = arrayBuffer;              break;
      case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = elementArrayBuffer;       break;
      case GL_FRAMEBUFFER_BINDING:              *params = framebuffer;              break;
      case GL_RENDERBUFFER_BINDING:             *params = renderbuffer;             break;
      case GL_CURRENT_PROGRAM:                  *params = currentProgram;           break;
      case GL_PACK_ALIGNMENT:                   *params = packAlignment;            break;
      case GL_UNPACK_ALIGNMENT:                 *params = unpackAlignment;          break;
      case GL_GENERATE_MIPMAP_HINT:             *params = generateMipmapHint;       break;
      case GL_ACTIVE_TEXTURE:                   *params = activeSampler;            break;
      case GL_STENCIL_FUNC:                     *params = stencilFunc;              break;
      case GL_STENCIL_REF:                      *params = stencilRef;               break;
      case GL_STENCIL_VALUE_MASK:               *params = stencilMask;              break;
      case GL_STENCIL_BACK_FUNC:                *params = stencilBackFunc;          break;
      case GL_STENCIL_BACK_REF:                 *params = stencilBackRef;           break;
      case GL_STENCIL_BACK_VALUE_MASK:          *params = stencilBackMask;          break;
      case GL_STENCIL_FAIL:                     *params = stencilFail;              break;
      case GL_STENCIL_PASS_DEPTH_FAIL:          *params = stencilPassDepthFail;     break;
      case GL_STENCIL_PASS_DEPTH_PASS:          *params = stencilPassDepthPass;     break;
      case GL_STENCIL_BACK_FAIL:                *params = stencilBackFail;          break;
      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = stencilBackPassDepthFail;     break;
      case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = stencilBackPassDepthPass;     break;
      case GL_DEPTH_FUNC:                       *params = depthFunc;                    break;
      case GL_BLEND_SRC_RGB:                    *params = sourceBlendRGB;               break;
      case GL_BLEND_SRC_ALPHA:                  *params = sourceBlendAlpha;             break;
      case GL_BLEND_DST_RGB:                    *params = destBlendRGB;                 break;
      case GL_BLEND_DST_ALPHA:                  *params = destBlendAlpha;               break;
      case GL_BLEND_EQUATION_RGB:               *params = blendEquationRGB;             break;
      case GL_BLEND_EQUATION_ALPHA:             *params = blendEquationAlpha;           break;
      case GL_STENCIL_WRITEMASK:                *params = stencilWritemask;             break;
      case GL_STENCIL_BACK_WRITEMASK:           *params = stencilBackWritemask;         break;
      case GL_STENCIL_CLEAR_VALUE:              *params = stencilClearValue;            break;
      case GL_SUBPIXEL_BITS:                    *params = 4;                            break;
      case GL_MAX_TEXTURE_SIZE:                 *params = gl::MAX_TEXTURE_SIZE;             break;
      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE;    break;
      case GL_SAMPLE_BUFFERS:                   *params = 0;                                break;
      case GL_SAMPLES:                          *params = 0;                                break;
      case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = gl::IMPLEMENTATION_COLOR_READ_TYPE;   break;
      case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
      case GL_MAX_VIEWPORT_DIMS:
        {
            int maxDimension = std::max((int)gl::MAX_RENDERBUFFER_SIZE, (int)gl::MAX_TEXTURE_SIZE);
            params[0] = maxDimension;
            params[1] = maxDimension;
        }
        break;
      case GL_VIEWPORT:
        params[0] = viewportX;
        params[1] = viewportY;
        params[2] = viewportWidth;
        params[3] = viewportHeight;
        break;
      case GL_SCISSOR_BOX:
        params[0] = scissorX;
        params[1] = scissorY;
        params[2] = scissorWidth;
        params[3] = scissorHeight;
        break;
      case GL_CULL_FACE_MODE:                   *params = cullMode;                 break;
      case GL_FRONT_FACE:                       *params = frontFace;                break;
      case GL_RED_BITS:
      case GL_GREEN_BITS:
      case GL_BLUE_BITS:
      case GL_ALPHA_BITS:
        {
            gl::Framebuffer *framebuffer = getFramebuffer();
            gl::Colorbuffer *colorbuffer = framebuffer->getColorbuffer();

            if (colorbuffer)
            {
                switch (pname)
                {
                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
                }
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_DEPTH_BITS:
        {
            gl::Framebuffer *framebuffer = getFramebuffer();
            gl::Depthbuffer *depthbuffer = framebuffer->getDepthbuffer();

            if (depthbuffer)
            {
                *params = depthbuffer->getDepthSize();
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_STENCIL_BITS:
        {
            gl::Framebuffer *framebuffer = getFramebuffer();
            gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();

            if (stencilbuffer)
            {
                *params = stencilbuffer->getStencilSize();
            }
            else
            {
                *params = 0;
            }
        }
        break;
      case GL_TEXTURE_BINDING_2D:
        {
            if (activeSampler < 0 || activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
            {
                error(GL_INVALID_OPERATION);
                return false;
            }

            *params = samplerTexture[SAMPLER_2D][activeSampler];
        }
        break;
      case GL_TEXTURE_BINDING_CUBE_MAP:
        {
            if (activeSampler < 0 || activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1)
            {
                error(GL_INVALID_OPERATION);
                return false;
            }

            *params = samplerTexture[SAMPLER_CUBE][activeSampler];
        }
        break;
      default:
        return false;
    }

    return true;
}

bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
{
    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
    // to the fact that it is stored internally as a float, and so would require conversion
    // if returned from Context::getIntegerv. Since this conversion is already implemented 
    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
    // application.
    switch (pname)
    {
      case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */ 
      case GL_SHADER_BINARY_FORMATS:
        {
            *type = GL_INT;
            *numParams = 0;
        }
        break;
      case GL_MAX_VERTEX_ATTRIBS:
      case GL_MAX_VERTEX_UNIFORM_VECTORS:
      case GL_MAX_VARYING_VECTORS:
      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
      case GL_MAX_TEXTURE_IMAGE_UNITS:
      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
      case GL_MAX_RENDERBUFFER_SIZE:
      case GL_NUM_SHADER_BINARY_FORMATS:
      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
      case GL_ARRAY_BUFFER_BINDING:
      case GL_FRAMEBUFFER_BINDING:
      case GL_RENDERBUFFER_BINDING:
      case GL_CURRENT_PROGRAM:
      case GL_PACK_ALIGNMENT:
      case GL_UNPACK_ALIGNMENT:
      case GL_GENERATE_MIPMAP_HINT:
      case GL_RED_BITS:
      case GL_GREEN_BITS:
      case GL_BLUE_BITS:
      case GL_ALPHA_BITS:
      case GL_DEPTH_BITS:
      case GL_STENCIL_BITS:
      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
      case GL_CULL_FACE_MODE:
      case GL_FRONT_FACE:
      case GL_ACTIVE_TEXTURE:
      case GL_STENCIL_FUNC:
      case GL_STENCIL_VALUE_MASK:
      case GL_STENCIL_REF:
      case GL_STENCIL_FAIL:
      case GL_STENCIL_PASS_DEPTH_FAIL:
      case GL_STENCIL_PASS_DEPTH_PASS:
      case GL_STENCIL_BACK_FUNC:
      case GL_STENCIL_BACK_VALUE_MASK:
      case GL_STENCIL_BACK_REF:
      case GL_STENCIL_BACK_FAIL:
      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
      case GL_DEPTH_FUNC:
      case GL_BLEND_SRC_RGB:
      case GL_BLEND_SRC_ALPHA:
      case GL_BLEND_DST_RGB:
      case GL_BLEND_DST_ALPHA:
      case GL_BLEND_EQUATION_RGB:
      case GL_BLEND_EQUATION_ALPHA:
      case GL_STENCIL_WRITEMASK:
      case GL_STENCIL_BACK_WRITEMASK:
      case GL_STENCIL_CLEAR_VALUE:
      case GL_SUBPIXEL_BITS:
      case GL_MAX_TEXTURE_SIZE:
      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
      case GL_SAMPLE_BUFFERS:
      case GL_SAMPLES:
      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
      case GL_TEXTURE_BINDING_2D:
      case GL_TEXTURE_BINDING_CUBE_MAP:
        {
            *type = GL_INT;
            *numParams = 1;
        }
        break;
      case GL_MAX_VIEWPORT_DIMS:
        {
            *type = GL_INT;
            *numParams = 2;
        }
        break;
      case GL_VIEWPORT:
      case GL_SCISSOR_BOX:
        {
            *type = GL_INT;
            *numParams = 4;
        }
        break;
      case GL_SHADER_COMPILER:
      case GL_SAMPLE_COVERAGE_INVERT:
      case GL_DEPTH_WRITEMASK:
        {
            *type = GL_BOOL;
            *numParams = 1;
        }
        break;
      case GL_COLOR_WRITEMASK:
        {
            *type = GL_BOOL;
            *numParams = 4;
        }
        break;
      case GL_POLYGON_OFFSET_FACTOR:
      case GL_POLYGON_OFFSET_UNITS:
      case GL_SAMPLE_COVERAGE_VALUE:
      case GL_DEPTH_CLEAR_VALUE:
      case GL_LINE_WIDTH:
        {
            *type = GL_FLOAT;
            *numParams = 1;
        }
        break;
      case GL_ALIASED_LINE_WIDTH_RANGE:
      case GL_ALIASED_POINT_SIZE_RANGE:
      case GL_DEPTH_RANGE:
        {
            *type = GL_FLOAT;
            *numParams = 2;
        }
        break;
      case GL_COLOR_CLEAR_VALUE:
        {
            *type = GL_FLOAT;
            *numParams = 4;
        }
        break;
      default:
        return false;
    }

    return true;
}

// Applies the render target surface, depth stencil surface, viewport rectangle and
// scissor rectangle to the Direct3D 9 device
bool Context::applyRenderTarget(bool ignoreViewport)
{
    IDirect3DDevice9 *device = getDevice();
    Framebuffer *framebufferObject = getFramebuffer();

    if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
    {
        return false;
    }

    IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
    IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();

    device->SetRenderTarget(0, renderTarget);
    device->SetDepthStencilSurface(depthStencil);

    D3DVIEWPORT9 viewport;
    D3DSURFACE_DESC desc;
    renderTarget->GetDesc(&desc);

    if (ignoreViewport)
    {
        viewport.X = 0;
        viewport.Y = 0;
        viewport.Width = desc.Width;
        viewport.Height = desc.Height;
        viewport.MinZ = 0.0f;
        viewport.MaxZ = 1.0f;
    }
    else
    {
        viewport.X = std::max(viewportX, 0);
        viewport.Y = std::max(viewportY, 0);
        viewport.Width = std::min(viewportWidth, (int)desc.Width - (int)viewport.X);
        viewport.Height = std::min(viewportHeight, (int)desc.Height - (int)viewport.Y);
        viewport.MinZ = clamp01(zNear);
        viewport.MaxZ = clamp01(zFar);
    }

    device->SetViewport(&viewport);

    if (scissorTest)
    {
        RECT rect = {scissorX,
                     scissorY,
                     scissorX + scissorWidth,
                     scissorY + scissorHeight};

        device->SetScissorRect(&rect);
        device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
    }
    else
    {
        device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
    }

    if (currentProgram)
    {
        D3DSURFACE_DESC description;
        renderTarget->GetDesc(&description);
        Program *programObject = getCurrentProgram();

        GLint halfPixelSize = programObject->getUniformLocation("gl_HalfPixelSize");
        GLfloat xy[2] = {1.0f / description.Width, 1.0f / description.Height};
        programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);

        GLint window = programObject->getUniformLocation("gl_Window");
        GLfloat whxy[4] = {viewportWidth / 2.0f, viewportHeight / 2.0f, (float)viewportX + viewportWidth / 2.0f, (float)viewportY + viewportHeight / 2.0f};
        programObject->setUniform4fv(window, 1, (GLfloat*)&whxy);

        GLint depth = programObject->getUniformLocation("gl_Depth");
        GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
        programObject->setUniform2fv(depth, 1, (GLfloat*)&dz);

        GLint near = programObject->getUniformLocation("gl_DepthRange.near");
        programObject->setUniform1fv(near, 1, &zNear);

        GLint far = programObject->getUniformLocation("gl_DepthRange.far");
        programObject->setUniform1fv(far, 1, &zFar);

        GLint diff = programObject->getUniformLocation("gl_DepthRange.diff");
        GLfloat zDiff = zFar - zNear;
        programObject->setUniform1fv(diff, 1, &zDiff);
    }

    return true;
}

// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
void Context::applyState()
{
    IDirect3DDevice9 *device = getDevice();
    Program *programObject = getCurrentProgram();

    GLint frontCCW = programObject->getUniformLocation("__frontCCW");
    GLint ccw = (frontFace == GL_CCW);
    programObject->setUniform1iv(frontCCW, 1, &ccw);

    if (cullFace)
    {
        device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(cullMode, frontFace));
    }
    else
    {
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
    }

    if (depthTest)
    {
        device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
        device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(depthFunc));
    }
    else
    {
        device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    }

    if (blend)
    {
        device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

        if (sourceBlendRGB != GL_CONSTANT_ALPHA && sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
            destBlendRGB != GL_CONSTANT_ALPHA && destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
        {
            device->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(blendColor));
        }
        else
        {
            device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(blendColor.alpha),
                                                                    unorm<8>(blendColor.alpha),
                                                                    unorm<8>(blendColor.alpha),
                                                                    unorm<8>(blendColor.alpha)));
        }

        device->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(sourceBlendRGB));
        device->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(destBlendRGB));
        device->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(blendEquationRGB));

        if (sourceBlendRGB != sourceBlendAlpha || destBlendRGB != destBlendAlpha || blendEquationRGB != blendEquationAlpha)
        {
            device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);

            device->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(sourceBlendAlpha));
            device->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(destBlendAlpha));
            device->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(blendEquationAlpha));

        }
        else
        {
            device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
        }
    }
    else
    {
        device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    }

    if (stencilTest)
    {
        device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
        device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);

        // FIXME: Unsupported by D3D9
        const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
        const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
        const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
        if(stencilWritemask != stencilBackWritemask || stencilRef != stencilBackRef || stencilMask != stencilBackMask)
        {
            ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
            return error(GL_INVALID_OPERATION);
        }

        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilWritemask);
        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(stencilFunc));

        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, stencilRef);   // FIXME: Clamp to range
        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilMask);

        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(stencilFail));
        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(stencilPassDepthFail));
        device->SetRenderState(frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(stencilPassDepthPass));

        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilBackWritemask);
        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(stencilBackFunc));

        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, stencilBackRef);   // FIXME: Clamp to range
        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilBackMask);

        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(stencilBackFail));
        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(stencilBackPassDepthFail));
        device->SetRenderState(frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(stencilBackPassDepthPass));
    }
    else
    {
        device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
    }

    device->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(colorMaskRed, colorMaskGreen, colorMaskBlue, colorMaskAlpha));
    device->SetRenderState(D3DRS_ZWRITEENABLE, depthMask ? TRUE : FALSE);

    if (polygonOffsetFill)
    {
        UNIMPLEMENTED();   // FIXME
    }

    if (sampleAlphaToCoverage)
    {
        UNIMPLEMENTED();   // FIXME
    }

    if (sampleCoverage)
    {
        UNIMPLEMENTED();   // FIXME: Ignore when SAMPLE_BUFFERS is not one
    }

    device->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE);
}

// Fill in the programAttribute field of the array of TranslatedAttributes based on the active GLSL program.
void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
{
    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
    {
        if (attributes[i].enabled)
        {
            attributes[i].programAttribute = getCurrentProgram()->getInputMapping(i);
        }
    }
}

// The indices parameter to glDrawElements can have two interpretations:
// - as a pointer into client memory
// - as an offset into the current GL_ELEMENT_ARRAY_BUFFER buffer
// Handle these cases here and return a pointer to the index data.
const Index *Context::adjustIndexPointer(const void *indices)
{
    if (elementArrayBuffer)
    {
        Buffer *buffer = getBuffer(elementArrayBuffer);
        return reinterpret_cast<const Index*>(static_cast<unsigned char*>(buffer->data()) + reinterpret_cast<GLsizei>(indices));
    }
    else
    {
        return static_cast<const Index*>(indices);
    }
}

void Context::applyVertexBuffer(GLint first, GLsizei count)
{
    TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];

    mVertexDataManager->preRenderValidate(first, count, translated);

    lookupAttributeMapping(translated);

    mBufferBackEnd->setupAttributesPreDraw(translated);
}

void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
{
    TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];

    mVertexDataManager->preRenderValidate(indexInfo, translated);

    lookupAttributeMapping(translated);

    mBufferBackEnd->setupAttributesPreDraw(translated);
}

// Applies the indices and element array bindings to the Direct3D 9 device
TranslatedIndexData Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type)
{
    TranslatedIndexData indexInfo = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(elementArrayBuffer), indices);
    mBufferBackEnd->setupIndicesPreDraw(indexInfo);
    return indexInfo;
}

// Applies the shaders and shader constants to the Direct3D 9 device
void Context::applyShaders()
{
    IDirect3DDevice9 *device = getDevice();
    Program *programObject = getCurrentProgram();
    IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader();
    IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader();

    device->SetVertexShader(vertexShader);
    device->SetPixelShader(pixelShader);

    programObject->applyUniforms();
}

// Applies the textures and sampler states to the Direct3D 9 device
void Context::applyTextures()
{
    IDirect3DDevice9 *device = getDevice();
    Program *programObject = getCurrentProgram();

    for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
    {
        int textureUnit = programObject->getSamplerMapping(sampler);
        if (textureUnit != -1)
        {
            SamplerType textureType = programObject->getSamplerType(sampler);

            Texture *texture = getSamplerTexture(textureUnit, textureType);

            if (texture->isComplete())
            {
                GLenum wrapS = texture->getWrapS();
                GLenum wrapT = texture->getWrapT();
                GLenum minFilter = texture->getMinFilter();
                GLenum magFilter = texture->getMagFilter();

                device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
                device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));

                device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
                D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
                es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
                device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter);
                device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter);

                device->SetTexture(sampler, texture->getTexture());
            }
            else
            {
                device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture());
            }
        }
        else
        {
            device->SetTexture(sampler, NULL);
        }
    }
}

void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
{
    Framebuffer *framebuffer = getFramebuffer();
    IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
    IDirect3DDevice9 *device = getDevice();

    D3DSURFACE_DESC desc;
    renderTarget->GetDesc(&desc);

    IDirect3DSurface9 *systemSurface;
    HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);

    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
    {
        return error(GL_OUT_OF_MEMORY);
    }

    ASSERT(SUCCEEDED(result));

    if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
    {
        UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
    }

    result = device->GetRenderTargetData(renderTarget, systemSurface);

    if (result == D3DERR_DRIVERINTERNALERROR)
    {
        systemSurface->Release();

        return error(GL_OUT_OF_MEMORY);
    }

    if (FAILED(result))
    {
        UNREACHABLE();
        systemSurface->Release();

        return;   // No sensible error to generate
    }

    D3DLOCKED_RECT lock;
    RECT rect = {std::max(x, 0),
                 std::max(y, 0),
                 std::min(x + width, (int)desc.Width),
                 std::min(y + height, (int)desc.Height)};

    result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);

    if (FAILED(result))
    {
        UNREACHABLE();
        systemSurface->Release();

        return;   // No sensible error to generate
    }

    unsigned char *source = (unsigned char*)lock.pBits;
    unsigned char *dest = (unsigned char*)pixels;

    for (int j = 0; j < rect.bottom - rect.top; j++)
    {
        for (int i = 0; i < rect.right - rect.left; i++)
        {
            float r;
            float g;
            float b;
            float a;

            switch (desc.Format)
            {
              case D3DFMT_R5G6B5:
                {
                    unsigned short rgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);

                    a = 1.0f;
                    b = (rgb & 0x001F) * (1.0f / 0x001F);
                    g = (rgb & 0x07E0) * (1.0f / 0x07E0);
                    r = (rgb & 0xF800) * (1.0f / 0xF800);
                }
                break;
              case D3DFMT_X1R5G5B5:
                {
                    unsigned short xrgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);

                    a = 1.0f;
                    b = (xrgb & 0x001F) * (1.0f / 0x001F);
                    g = (xrgb & 0x03E0) * (1.0f / 0x03E0);
                    r = (xrgb & 0x7C00) * (1.0f / 0x7C00);
                }
                break;
              case D3DFMT_A1R5G5B5:
                {
                    unsigned short argb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);

                    a = (argb & 0x8000) ? 1.0f : 0.0f;
                    b = (argb & 0x001F) * (1.0f / 0x001F);
                    g = (argb & 0x03E0) * (1.0f / 0x03E0);
                    r = (argb & 0x7C00) * (1.0f / 0x7C00);
                }
                break;
              case D3DFMT_A8R8G8B8:
                {
                    unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch);

                    a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
                    b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
                    g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
                    r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
                }
                break;
              case D3DFMT_X8R8G8B8:
                {
                    unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * lock.Pitch);

                    a = 1.0f;
                    b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
                    g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
                    r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
                }
                break;
              case D3DFMT_A2R10G10B10:
                {
                    unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch);

                    a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
                    b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
                    g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
                    r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
                }
                break;
              default:
                UNIMPLEMENTED();   // FIXME
                UNREACHABLE();
            }

            switch (format)
            {
              case GL_RGBA:
                switch (type)
                {
                  case GL_UNSIGNED_BYTE:
                    dest[4 * (i + j * width) + 0] = (unsigned char)(255 * r + 0.5f);
                    dest[4 * (i + j * width) + 1] = (unsigned char)(255 * g + 0.5f);
                    dest[4 * (i + j * width) + 2] = (unsigned char)(255 * b + 0.5f);
                    dest[4 * (i + j * width) + 3] = (unsigned char)(255 * a + 0.5f);
                    break;
                  default: UNREACHABLE();
                }
                break;
              case IMPLEMENTATION_COLOR_READ_FORMAT:
                switch (type)
                {
                  case IMPLEMENTATION_COLOR_READ_TYPE:
                    break;
                  default: UNREACHABLE();
                }
                break;
              default: UNREACHABLE();
            }
        }
    }

    systemSurface->UnlockRect();

    systemSurface->Release();
}

void Context::clear(GLbitfield mask)
{
    IDirect3DDevice9 *device = getDevice();
    DWORD flags = 0;

    if (mask & GL_COLOR_BUFFER_BIT)
    {
        mask &= ~GL_COLOR_BUFFER_BIT;
        flags |= D3DCLEAR_TARGET;
    }

    if (mask & GL_DEPTH_BUFFER_BIT)
    {
        mask &= ~GL_DEPTH_BUFFER_BIT;
        if (depthMask)
        {
            flags |= D3DCLEAR_ZBUFFER;
        }
    }

    Framebuffer *framebufferObject = getFramebuffer();
    IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();

    GLuint stencilUnmasked = 0x0;

    if ((mask & GL_STENCIL_BUFFER_BIT) && depthStencil)
    {
        D3DSURFACE_DESC desc;
        depthStencil->GetDesc(&desc);

        mask &= ~GL_STENCIL_BUFFER_BIT;
        unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
        stencilUnmasked = (0x1 << stencilSize) - 1;

        if (stencilUnmasked != 0x0)
        {
            flags |= D3DCLEAR_STENCIL;
        }
    }

    if (mask != 0)
    {
        return error(GL_INVALID_VALUE);
    }

    applyRenderTarget(true);   // Clips the clear to the scissor rectangle but not the viewport

    D3DCOLOR color = D3DCOLOR_ARGB(unorm<8>(colorClearValue.alpha), unorm<8>(colorClearValue.red), unorm<8>(colorClearValue.green), unorm<8>(colorClearValue.blue));
    float depth = clamp01(depthClearValue);
    int stencil = stencilClearValue & 0x000000FF;

    IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();

    D3DSURFACE_DESC desc;
    renderTarget->GetDesc(&desc);

    bool alphaUnmasked = (es2dx::GetAlphaSize(desc.Format) == 0) || colorMaskAlpha;

    const bool needMaskedStencilClear = (flags & D3DCLEAR_STENCIL) &&
                                        (stencilWritemask & stencilUnmasked) != stencilUnmasked;
    const bool needMaskedColorClear = (flags & D3DCLEAR_TARGET) &&
                                      !(colorMaskRed && colorMaskGreen &&
                                        colorMaskBlue && alphaUnmasked);

    if (needMaskedColorClear || needMaskedStencilClear)
    {
        device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
        device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
        device->SetRenderState(D3DRS_ZENABLE, FALSE);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
        device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
        device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
        device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
        device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);

        if (flags & D3DCLEAR_TARGET)
        {
            device->SetRenderState(D3DRS_COLORWRITEENABLE, (colorMaskRed   ? D3DCOLORWRITEENABLE_RED   : 0) |
                                                           (colorMaskGreen ? D3DCOLORWRITEENABLE_GREEN : 0) |
                                                           (colorMaskBlue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
                                                           (colorMaskAlpha ? D3DCOLORWRITEENABLE_ALPHA : 0));
        }
        else
        {
            device->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
        }

        if (stencilUnmasked != 0x0 && (flags & D3DCLEAR_STENCIL))
        {
            device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
            device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
            device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
            device->SetRenderState(D3DRS_STENCILREF, stencil);
            device->SetRenderState(D3DRS_STENCILWRITEMASK, stencilWritemask);
            device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
            device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
            device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
        }
        else
        {
            device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
        }

        device->SetPixelShader(NULL);
        device->SetVertexShader(NULL);
        device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);

        struct Vertex
        {
            float x, y, z, w;
            D3DCOLOR diffuse;
        };

        Vertex quad[4];
        quad[0].x = 0.0f;
        quad[0].y = (float)desc.Height;
        quad[0].z = 0.0f;
        quad[0].w = 1.0f;
        quad[0].diffuse = color;

        quad[1].x = (float)desc.Width;
        quad[1].y = (float)desc.Height;
        quad[1].z = 0.0f;
        quad[1].w = 1.0f;
        quad[1].diffuse = color;

        quad[2].x = 0.0f;
        quad[2].y = 0.0f;
        quad[2].z = 0.0f;
        quad[2].w = 1.0f;
        quad[2].diffuse = color;

        quad[3].x = (float)desc.Width;
        quad[3].y = 0.0f;
        quad[3].z = 0.0f;
        quad[3].w = 1.0f;
        quad[3].diffuse = color;

        device->BeginScene();
        device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(Vertex));
        device->EndScene();

        if (flags & D3DCLEAR_ZBUFFER)
        {
            device->SetRenderState(D3DRS_ZENABLE, TRUE);
            device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
            device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
        }
    }
    else
    {
        device->Clear(0, NULL, flags, color, depth, stencil);
    }
}

void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
{
    if (!currentProgram)
    {
        return error(GL_INVALID_OPERATION);
    }

    IDirect3DDevice9 *device = getDevice();
    D3DPRIMITIVETYPE primitiveType;
    int primitiveCount;

    if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
        return error(GL_INVALID_ENUM);

    if (primitiveCount <= 0)
    {
        return;
    }

    if (!applyRenderTarget(false))
    {
        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
    }

    applyState();
    applyVertexBuffer(first, count);
    applyShaders();
    applyTextures();

    if (!cullSkipsDraw(mode))
    {
        device->BeginScene();
        device->DrawPrimitive(primitiveType, 0, primitiveCount);
        device->EndScene();
    }
}

void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
{
    if (!currentProgram)
    {
        return error(GL_INVALID_OPERATION);
    }

    if (!indices && !elementArrayBuffer)
    {
        return error(GL_INVALID_OPERATION);
    }

    IDirect3DDevice9 *device = getDevice();
    D3DPRIMITIVETYPE primitiveType;
    int primitiveCount;

    if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
        return error(GL_INVALID_ENUM);

    if (primitiveCount <= 0)
    {
        return;
    }

    if (!applyRenderTarget(false))
    {
        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
    }

    applyState();
    TranslatedIndexData indexInfo = applyIndexBuffer(indices, count, mode, type);
    applyVertexBuffer(indexInfo);
    applyShaders();
    applyTextures();

    if (!cullSkipsDraw(mode))
    {
        device->BeginScene();
        device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/sizeof(Index), primitiveCount);
        device->EndScene();
    }
}

void Context::finish()
{
    IDirect3DDevice9 *device = getDevice();
    IDirect3DQuery9 *occlusionQuery = NULL;

    HRESULT result = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery);

    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
    {
        return error(GL_OUT_OF_MEMORY);
    }

    ASSERT(SUCCEEDED(result));

    if (occlusionQuery)
    {
        occlusionQuery->Issue(D3DISSUE_BEGIN);

        // Render something outside the render target
        device->SetPixelShader(NULL);
        device->SetVertexShader(NULL);
        device->SetFVF(D3DFVF_XYZRHW);
        float data[4] = {-1.0f, -1.0f, -1.0f, 1.0f};
        device->BeginScene();
        device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data));
        device->EndScene();

        occlusionQuery->Issue(D3DISSUE_END);

        while (occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
        {
            // Keep polling, but allow other threads to do something useful first
            Sleep(0);
        }

        occlusionQuery->Release();
    }
}

void Context::flush()
{
    IDirect3DDevice9 *device = getDevice();
    IDirect3DQuery9 *eventQuery = NULL;

    HRESULT result = device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery);

    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
    {
        return error(GL_OUT_OF_MEMORY);
    }

    ASSERT(SUCCEEDED(result));

    if (eventQuery)
    {
        eventQuery->Issue(D3DISSUE_END);

        while (eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
        {
            // Keep polling, but allow other threads to do something useful first
            Sleep(0);
        }

        eventQuery->Release();
    }
}

void Context::recordInvalidEnum()
{
    mInvalidEnum = true;
}

void Context::recordInvalidValue()
{
    mInvalidValue = true;
}

void Context::recordInvalidOperation()
{
    mInvalidOperation = true;
}

void Context::recordOutOfMemory()
{
    mOutOfMemory = true;
}

void Context::recordInvalidFramebufferOperation()
{
    mInvalidFramebufferOperation = true;
}

// Get one of the recorded errors and clear its flag, if any.
// [OpenGL ES 2.0.24] section 2.5 page 13.
GLenum Context::getError()
{
    if (mInvalidEnum)
    {
        mInvalidEnum = false;

        return GL_INVALID_ENUM;
    }

    if (mInvalidValue)
    {
        mInvalidValue = false;

        return GL_INVALID_VALUE;
    }

    if (mInvalidOperation)
    {
        mInvalidOperation = false;

        return GL_INVALID_OPERATION;
    }

    if (mOutOfMemory)
    {
        mOutOfMemory = false;

        return GL_OUT_OF_MEMORY;
    }

    if (mInvalidFramebufferOperation)
    {
        mInvalidFramebufferOperation = false;

        return GL_INVALID_FRAMEBUFFER_OPERATION;
    }

    return GL_NO_ERROR;
}

const char *Context::getPixelShaderProfile()
{
    return mPsProfile;
}

const char *Context::getVertexShaderProfile()
{
    return mVsProfile;
}

void Context::detachBuffer(GLuint buffer)
{
    // [OpenGL ES 2.0.24] section 2.9 page 22:
    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
    // (i.e. in the thread that called Delete-Buffers) are reset to zero.

    if (arrayBuffer == buffer)
    {
        arrayBuffer = 0;
    }

    if (elementArrayBuffer == buffer)
    {
        elementArrayBuffer = 0;
    }

    for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
    {
        if (vertexAttribute[attribute].mBoundBuffer == buffer)
        {
            vertexAttribute[attribute].mBoundBuffer = 0;
        }
    }
}

void Context::detachTexture(GLuint texture)
{
    // [OpenGL ES 2.0.24] section 3.8 page 84:
    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
    // rebound to texture object zero

    for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
    {
        for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
        {
            if (samplerTexture[type][sampler] == texture)
            {
                samplerTexture[type][sampler] = 0;
            }
        }
    }

    // [OpenGL ES 2.0.24] section 4.4 page 112:
    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
    // image was attached in the currently bound framebuffer.

    Framebuffer *framebuffer = getFramebuffer();

    if (framebuffer)
    {
        framebuffer->detachTexture(texture);
    }
}

void Context::detachFramebuffer(GLuint framebuffer)
{
    // [OpenGL ES 2.0.24] section 4.4 page 107:
    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.

    if (this->framebuffer == framebuffer)
    {
        bindFramebuffer(0);
    }
}

void Context::detachRenderbuffer(GLuint renderbuffer)
{
    // [OpenGL ES 2.0.24] section 4.4 page 109:
    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
    // had been executed with the target RENDERBUFFER and name of zero.

    if (this->renderbuffer == renderbuffer)
    {
        bindRenderbuffer(0);
    }

    // [OpenGL ES 2.0.24] section 4.4 page 111:
    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
    // point to which this image was attached in the currently bound framebuffer.

    Framebuffer *framebuffer = getFramebuffer();

    if (framebuffer)
    {
        framebuffer->detachRenderbuffer(renderbuffer);
    }
}

Texture *Context::getIncompleteTexture(SamplerType type)
{
    Texture *t = mIncompleteTextures[type];

    if (t == NULL)
    {
        static const GLubyte color[] = { 0, 0, 0, 255 };

        switch (type)
        {
          default:
            UNREACHABLE();
            // default falls through to SAMPLER_2D

          case SAMPLER_2D:
            {
                Texture2D *incomplete2d = new Texture2D;
                incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
                t = incomplete2d;
            }
            break;

          case SAMPLER_CUBE:
            {
              TextureCubeMap *incompleteCube = new TextureCubeMap;

              incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
              incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
              incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
              incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
              incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
              incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);

              t = incompleteCube;
            }
            break;
        }

        mIncompleteTextures[type] = t;
    }

    return t;
}

bool Context::cullSkipsDraw(GLenum primitiveType)
{
    if (cullFace && cullMode == GL_FRONT_AND_BACK &&
        (primitiveType == GL_TRIANGLES || primitiveType == GL_TRIANGLE_FAN || primitiveType == GL_TRIANGLE_STRIP))
    {
        return true;
    }
    else
    {
        return false;
    }
}

}

extern "C"
{
gl::Context *glCreateContext(const egl::Config *config)
{
    return new gl::Context(config);
}

void glDestroyContext(gl::Context *context)
{
    delete context;

    if (context == gl::getContext())
    {
        gl::makeCurrent(NULL, NULL, NULL);
    }
}

void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
{
    gl::makeCurrent(context, display, surface);
}

gl::Context *glGetCurrentContext()
{
    return gl::getContext();
}
}
