blob: c80aecca79b85c02e176f20a4c0056766569441d [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_RS_BUILD_FOR_HOST
#include <GLES/gl.h>
#include <GLES/glext.h>
#include "rsContext.h"
#else
#include "rsContextHostStub.h"
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#endif //ANDROID_RS_BUILD_FOR_HOST
#include "rsSampler.h"
using namespace android;
using namespace android::renderscript;
Sampler::Sampler(Context *rsc) : ObjectBase(rsc) {
// Should not get called.
rsAssert(0);
}
Sampler::Sampler(Context *rsc,
RsSamplerValue magFilter,
RsSamplerValue minFilter,
RsSamplerValue wrapS,
RsSamplerValue wrapT,
RsSamplerValue wrapR,
float aniso) : ObjectBase(rsc) {
mMagFilter = magFilter;
mMinFilter = minFilter;
mWrapS = wrapS;
mWrapT = wrapT;
mWrapR = wrapR;
mAniso = aniso;
}
Sampler::~Sampler() {
}
void Sampler::setupGL(const Context *rsc, const Allocation *tex) {
GLenum trans[] = {
GL_NEAREST, //RS_SAMPLER_NEAREST,
GL_LINEAR, //RS_SAMPLER_LINEAR,
GL_LINEAR_MIPMAP_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
GL_REPEAT, //RS_SAMPLER_WRAP,
GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
GL_LINEAR_MIPMAP_NEAREST, //RS_SAMPLER_LINEAR_MIP_NEAREST
};
GLenum transNP[] = {
GL_NEAREST, //RS_SAMPLER_NEAREST,
GL_LINEAR, //RS_SAMPLER_LINEAR,
GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_LINEAR,
GL_CLAMP_TO_EDGE, //RS_SAMPLER_WRAP,
GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
GL_LINEAR, //RS_SAMPLER_LINEAR_MIP_NEAREST,
};
// This tells us the correct texture type
GLenum target = (GLenum)tex->getGLTarget();
if (!rsc->ext_OES_texture_npot() && tex->getType()->getIsNp2()) {
if (tex->getHasGraphicsMipmaps() &&
(rsc->ext_GL_NV_texture_npot_2D_mipmap() || rsc->ext_GL_IMG_texture_npot())) {
if (rsc->ext_GL_NV_texture_npot_2D_mipmap()) {
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
} else {
switch (trans[mMinFilter]) {
case GL_LINEAR_MIPMAP_LINEAR:
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
break;
default:
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
break;
}
}
} else {
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
}
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]);
glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[mWrapS]);
glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[mWrapT]);
} else {
if (tex->getHasGraphicsMipmaps()) {
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
} else {
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
}
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]);
glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[mWrapS]);
glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[mWrapT]);
}
float anisoValue = rsMin(rsc->ext_texture_max_aniso(), mAniso);
if (rsc->ext_texture_max_aniso() > 1.0f) {
glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
}
rsc->checkError("Sampler::setupGL2 tex env");
}
void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
ss->mSamplers[slot].set(this);
mBoundSlot = slot;
}
void Sampler::unbindFromContext(SamplerState *ss) {
int32_t slot = mBoundSlot;
mBoundSlot = -1;
ss->mSamplers[slot].clear();
}
void Sampler::serialize(OStream *stream) const {
}
Sampler *Sampler::createFromStream(Context *rsc, IStream *stream) {
return NULL;
}
////////////////////////////////
namespace android {
namespace renderscript {
void rsi_SamplerBegin(Context *rsc) {
SamplerState * ss = &rsc->mStateSampler;
ss->mMagFilter = RS_SAMPLER_LINEAR;
ss->mMinFilter = RS_SAMPLER_LINEAR;
ss->mWrapS = RS_SAMPLER_WRAP;
ss->mWrapT = RS_SAMPLER_WRAP;
ss->mWrapR = RS_SAMPLER_WRAP;
ss->mAniso = 1.0f;
}
void rsi_SamplerSet(Context *rsc, RsSamplerParam param, RsSamplerValue value) {
SamplerState * ss = &rsc->mStateSampler;
switch (param) {
case RS_SAMPLER_MAG_FILTER:
ss->mMagFilter = value;
break;
case RS_SAMPLER_MIN_FILTER:
ss->mMinFilter = value;
break;
case RS_SAMPLER_WRAP_S:
ss->mWrapS = value;
break;
case RS_SAMPLER_WRAP_T:
ss->mWrapT = value;
break;
case RS_SAMPLER_WRAP_R:
ss->mWrapR = value;
break;
default:
LOGE("Attempting to set invalid value on sampler");
break;
}
}
void rsi_SamplerSet2(Context *rsc, RsSamplerParam param, float value) {
SamplerState * ss = &rsc->mStateSampler;
switch (param) {
case RS_SAMPLER_ANISO:
ss->mAniso = value;
break;
default:
LOGE("Attempting to set invalid value on sampler");
break;
}
}
RsSampler rsi_SamplerCreate(Context *rsc) {
SamplerState * ss = &rsc->mStateSampler;
Sampler * s = new Sampler(rsc,
ss->mMagFilter,
ss->mMinFilter,
ss->mWrapS,
ss->mWrapT,
ss->mWrapR,
ss->mAniso);
s->incUserRef();
return s;
}
}}