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

// Sampler.cpp : Implements the Sampler class, which represents a GLES 3
// sampler object. Sampler objects store some state needed to sample textures.

#include "libANGLE/Sampler.h"
#include "libANGLE/Context.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/GLImplFactory.h"
#include "libANGLE/renderer/SamplerImpl.h"

namespace gl
{

Sampler::Sampler(rx::GLImplFactory *factory, SamplerID id)
    : RefCountObject(factory->generateSerial(), id),
      mState(),
      mDirty(true),
      mSampler(factory->createSampler(mState)),
      mLabel()
{}

Sampler::~Sampler()
{
    SafeDelete(mSampler);
}

void Sampler::onDestroy(const Context *context)
{
    if (context && context->retainIdUntilObjectDestroyed())
    {
        context->onSamplerDestroy(this);
    }

    if (mSampler)
    {
        mSampler->onDestroy(context);
    }
}

angle::Result Sampler::setLabel(const Context *context, const std::string &label)
{
    mLabel = label;

    if (mSampler)
    {
        return mSampler->onLabelUpdate(context);
    }
    return angle::Result::Continue;
}

const std::string &Sampler::getLabel() const
{
    return mLabel;
}

void Sampler::setMinFilter(const Context *context, GLenum minFilter)
{
    mState.setMinFilter(minFilter);
    signalDirtyState();
}

GLenum Sampler::getMinFilter() const
{
    return mState.getMinFilter();
}

void Sampler::setMagFilter(const Context *context, GLenum magFilter)
{
    mState.setMagFilter(magFilter);
    signalDirtyState();
}

GLenum Sampler::getMagFilter() const
{
    return mState.getMagFilter();
}

void Sampler::setWrapS(const Context *context, GLenum wrapS)
{
    mState.setWrapS(wrapS);
    signalDirtyState();
}

GLenum Sampler::getWrapS() const
{
    return mState.getWrapS();
}

void Sampler::setWrapT(const Context *context, GLenum wrapT)
{
    mState.setWrapT(wrapT);
    signalDirtyState();
}

GLenum Sampler::getWrapT() const
{
    return mState.getWrapT();
}

void Sampler::setWrapR(const Context *context, GLenum wrapR)
{
    mState.setWrapR(wrapR);
    signalDirtyState();
}

GLenum Sampler::getWrapR() const
{
    return mState.getWrapR();
}

void Sampler::setMaxAnisotropy(const Context *context, float maxAnisotropy)
{
    mState.setMaxAnisotropy(maxAnisotropy);
    signalDirtyState();
}

float Sampler::getMaxAnisotropy() const
{
    return mState.getMaxAnisotropy();
}

void Sampler::setMinLod(const Context *context, GLfloat minLod)
{
    mState.setMinLod(minLod);
    signalDirtyState();
}

GLfloat Sampler::getMinLod() const
{
    return mState.getMinLod();
}

void Sampler::setMaxLod(const Context *context, GLfloat maxLod)
{
    mState.setMaxLod(maxLod);
    signalDirtyState();
}

GLfloat Sampler::getMaxLod() const
{
    return mState.getMaxLod();
}

void Sampler::setLodBias(const Context *context, GLfloat lodBias)
{
    mState.setLodBias(lodBias);
    signalDirtyState();
}

GLfloat Sampler::getLodBias() const
{
    return mState.getLodBias();
}

void Sampler::setCompareMode(const Context *context, GLenum compareMode)
{
    mState.setCompareMode(compareMode);
    signalDirtyState();
}

GLenum Sampler::getCompareMode() const
{
    return mState.getCompareMode();
}

void Sampler::setCompareFunc(const Context *context, GLenum compareFunc)
{
    mState.setCompareFunc(compareFunc);
    signalDirtyState();
}

GLenum Sampler::getCompareFunc() const
{
    return mState.getCompareFunc();
}

void Sampler::setSRGBDecode(const Context *context, GLenum sRGBDecode)
{
    mState.setSRGBDecode(sRGBDecode);
    signalDirtyState();
}

GLenum Sampler::getSRGBDecode() const
{
    return mState.getSRGBDecode();
}

void Sampler::setBorderColor(const Context *context, const ColorGeneric &color)
{
    mState.setBorderColor(color);
    signalDirtyState();
}

const ColorGeneric &Sampler::getBorderColor() const
{
    return mState.getBorderColor();
}

rx::SamplerImpl *Sampler::getImplementation() const
{
    return mSampler;
}

angle::Result Sampler::syncState(const Context *context)
{
    ASSERT(isDirty());
    angle::Result result = mSampler->syncState(context, mDirty);
    mDirty               = result != angle::Result::Continue;
    return result;
}

void Sampler::signalDirtyState()
{
    mDirty = true;
    onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
}

}  // namespace gl
