//
// 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)
    {
        if (texture != 0)
        {
            mTextureMap[texture] = new Texture2D();
        }
        else   // Special case: 0 refers to different initial textures based on the target
        {
            mTextureMap[0] = mTexture2DZero;
        }
    }

    texture2D = texture;

    samplerTexture[SAMPLER_2D][activeSampler] = texture;
}

void Context::bindTextureCubeMap(GLuint texture)
{
    if (!getTexture(texture) || texture == 0)
    {
        if (texture != 0)
        {
            mTextureMap[texture] = new TextureCubeMap();
        }
        else   // Special case: 0 refers to different initial textures based on the target
        {
            mTextureMap[0] = mTextureCubeMapZero;
        }
    }

    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)
{
    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)
{
    return getTexture(samplerTexture[type][sampler]);
}

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();
}
}
