//
// 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.
//

// Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.

#include "Framebuffer.h"

#include "main.h"
#include "Renderbuffer.h"
#include "Texture.h"
#include "utilities.h"

namespace gl
{

Framebuffer::Framebuffer()
{
    mColorbufferType = GL_NONE;
    mDepthbufferType = GL_NONE;
    mStencilbufferType = GL_NONE;
}

Framebuffer::~Framebuffer()
{
    mColorbufferPointer.set(NULL);
    mDepthbufferPointer.set(NULL);
    mStencilbufferPointer.set(NULL);
}

Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
{
    Context *context = getContext();
    Renderbuffer *buffer = NULL;

    if(type == GL_NONE)
    {
        buffer = NULL;
    }
    else if(type == GL_RENDERBUFFER)
    {
        buffer = context->getRenderbuffer(handle);
    }
    else if(IsTextureTarget(type))
    {
        buffer = context->getTexture(handle)->getRenderbuffer(type);
    }
    else
    {
        UNREACHABLE();
    }

    return buffer;
}

void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
{
    mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
    mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
}

void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
{
    mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
    mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
}

void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
{
    mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
    mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
}

void Framebuffer::detachTexture(GLuint texture)
{
    if(mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
    {
        mColorbufferType = GL_NONE;
        mColorbufferPointer.set(NULL);
    }

    if(mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
    {
        mDepthbufferType = GL_NONE;
        mDepthbufferPointer.set(NULL);
    }

    if(mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
    {
        mStencilbufferType = GL_NONE;
        mStencilbufferPointer.set(NULL);
    }
}

void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
    if(mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
    {
        mColorbufferType = GL_NONE;
        mColorbufferPointer.set(NULL);
    }

    if(mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
    {
        mDepthbufferType = GL_NONE;
        mDepthbufferPointer.set(NULL);
    }

    if(mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
    {
        mStencilbufferType = GL_NONE;
        mStencilbufferPointer.set(NULL);
    }
}

unsigned int Framebuffer::getRenderTargetSerial()
{
    Renderbuffer *colorbuffer = mColorbufferPointer.get();

    if(colorbuffer)
    {
        return colorbuffer->getSerial();
    }

    return 0;
}

Image *Framebuffer::getRenderTarget()
{
    Renderbuffer *colorbuffer = mColorbufferPointer.get();

    if(colorbuffer)
    {
        return colorbuffer->getRenderTarget();
    }

    return NULL;
}

Image *Framebuffer::getDepthStencil()
{
    Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
    
    if(!depthstencilbuffer)
    {
        depthstencilbuffer = mStencilbufferPointer.get();
    }

    if(depthstencilbuffer)
    {
        return depthstencilbuffer->getDepthStencil();
    }

    return NULL;
}

unsigned int Framebuffer::getDepthbufferSerial()
{
    Renderbuffer *depthbuffer = mDepthbufferPointer.get();

    if(depthbuffer)
    {
        return depthbuffer->getSerial();
    }

    return 0;
}

unsigned int Framebuffer::getStencilbufferSerial()
{
    Renderbuffer *stencilbuffer = mStencilbufferPointer.get();

    if(stencilbuffer)
    {
        return stencilbuffer->getSerial();
    }

    return 0;
}

Colorbuffer *Framebuffer::getColorbuffer()
{
    Renderbuffer *rb = mColorbufferPointer.get();

    if(rb != NULL && rb->isColorbuffer())
    {
        return static_cast<Colorbuffer*>(rb->getStorage());
    }
    else
    {
        return NULL;
    }
}

DepthStencilbuffer *Framebuffer::getDepthbuffer()
{
    Renderbuffer *rb = mDepthbufferPointer.get();

    if(rb != NULL && rb->isDepthbuffer())
    {
        return static_cast<DepthStencilbuffer*>(rb->getStorage());
    }
    else
    {
        return NULL;
    }
}

DepthStencilbuffer *Framebuffer::getStencilbuffer()
{
    Renderbuffer *rb = mStencilbufferPointer.get();

    if(rb != NULL && rb->isStencilbuffer())
    {
        return static_cast<DepthStencilbuffer*>(rb->getStorage());
    }
    else
    {
        return NULL;
    }
}

GLenum Framebuffer::getColorbufferType()
{
    return mColorbufferType;
}

GLenum Framebuffer::getDepthbufferType()
{
    return mDepthbufferType;
}

GLenum Framebuffer::getStencilbufferType()
{
    return mStencilbufferType;
}

GLuint Framebuffer::getColorbufferHandle()
{
    return mColorbufferPointer.id();
}

GLuint Framebuffer::getDepthbufferHandle()
{
    return mDepthbufferPointer.id();
}

GLuint Framebuffer::getStencilbufferHandle()
{
    return mStencilbufferPointer.id();
}

bool Framebuffer::hasStencil()
{
    if(mStencilbufferType != GL_NONE)
    {
        DepthStencilbuffer *stencilbufferObject = getStencilbuffer();

        if(stencilbufferObject)
        {
            return stencilbufferObject->getStencilSize() > 0;
        }
    }

    return false;
}

GLenum Framebuffer::completeness()
{
    int width = 0;
    int height = 0;
    int samples = -1;

    if(mColorbufferType != GL_NONE)
    {
        Colorbuffer *colorbuffer = getColorbuffer();

        if(!colorbuffer)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(mColorbufferType == GL_RENDERBUFFER)
        {
            if(!IsColorRenderable(colorbuffer->getFormat()))
            {
                return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
            }
        }
        else if(IsTextureTarget(mColorbufferType))
        {
            if(IsCompressed(colorbuffer->getFormat()))
            {
                return GL_FRAMEBUFFER_UNSUPPORTED;
            }

            if(colorbuffer->getFormat() == GL_LUMINANCE || colorbuffer->getFormat() == GL_LUMINANCE_ALPHA)
            {
                return GL_FRAMEBUFFER_UNSUPPORTED;
            }
        }
        else UNREACHABLE();

        width = colorbuffer->getWidth();
        height = colorbuffer->getHeight();
        samples = colorbuffer->getSamples();
    }
    else
    {
        return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
    }

    DepthStencilbuffer *depthbuffer = NULL;
    DepthStencilbuffer *stencilbuffer = NULL;

    if(mDepthbufferType != GL_NONE)
    {
        if(mDepthbufferType != GL_RENDERBUFFER)
        {
            return GL_FRAMEBUFFER_UNSUPPORTED;   // Requires GL_OES_depth_texture
        }

        depthbuffer = getDepthbuffer();

        if(!depthbuffer)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(width == 0)
        {
            width = depthbuffer->getWidth();
            height = depthbuffer->getHeight();
        }
        else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
        {
            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
        }

        if(samples == -1)
        {
            samples = depthbuffer->getSamples();
        }
        else if(samples != depthbuffer->getSamples())
        {
            return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
        }
    }

    if(mStencilbufferType != GL_NONE)
    {
        if(mStencilbufferType != GL_RENDERBUFFER)
        {
            return GL_FRAMEBUFFER_UNSUPPORTED;
        }

        stencilbuffer = getStencilbuffer();

        if(!stencilbuffer)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
        {
            return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
        }

        if(width == 0)
        {
            width = stencilbuffer->getWidth();
            height = stencilbuffer->getHeight();
        }
        else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
        {
            return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
        }

        if(samples == -1)
        {
            samples = stencilbuffer->getSamples();
        }
        else if(samples != stencilbuffer->getSamples())
        {
            return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
        }
    }

    if(mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
    {
        if(depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
           stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
           depthbuffer->getSerial() != stencilbuffer->getSerial())
        {
            return GL_FRAMEBUFFER_UNSUPPORTED;
        }
    }

    return GL_FRAMEBUFFER_COMPLETE;
}

DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
{
    mColorbufferType = GL_RENDERBUFFER;
    mDepthbufferType = (depthStencil->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
    mStencilbufferType = (depthStencil->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;

    mColorbufferPointer.set(new Renderbuffer(0, color));

    Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
    mDepthbufferPointer.set(depthStencilRenderbuffer);
    mStencilbufferPointer.set(depthStencilRenderbuffer);
}

int Framebuffer::getSamples()
{
    if(completeness() == GL_FRAMEBUFFER_COMPLETE)
    {
        return getColorbuffer()->getSamples();
    }
    else
    {
        return 0;
    }
}

GLenum DefaultFramebuffer::completeness()
{
    // The default framebuffer should always be complete
    ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);

    return GL_FRAMEBUFFER_COMPLETE;
}

}
