EmuGL: GLESv2 support for OES_EGL_image_external
Change-Id: I8911328d5dcccdf4731bd2d8fd953c12fdec5f1b
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
#include "GLSharedGroup.h"
|
||||
|
||||
/**** BufferData ****/
|
||||
@@ -53,6 +69,15 @@ void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type
|
||||
m_Indexes[index].appBase = 0;
|
||||
}
|
||||
m_Indexes[index].hostLocsPerElement = 1;
|
||||
m_Indexes[index].flags = 0;
|
||||
m_Indexes[index].samplerValue = 0;
|
||||
}
|
||||
|
||||
void ProgramData::setIndexFlags(GLuint index, GLuint flags)
|
||||
{
|
||||
if (index >= m_numIndexes)
|
||||
return;
|
||||
m_Indexes[index].flags |= flags;
|
||||
}
|
||||
|
||||
GLuint ProgramData::getIndexForLocation(GLint location)
|
||||
@@ -123,13 +148,77 @@ GLint ProgramData::locationWARAppToHost(GLint appLoc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
GLint ProgramData::getNextSamplerUniform(GLint index, GLint* val, GLenum* target)
|
||||
{
|
||||
for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {
|
||||
if (m_Indexes[i].type == GL_SAMPLER_2D) {
|
||||
if (val) *val = m_Indexes[i].samplerValue;
|
||||
if (target) {
|
||||
if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
|
||||
*target = GL_TEXTURE_EXTERNAL_OES;
|
||||
} else {
|
||||
*target = GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target)
|
||||
{
|
||||
for (GLuint i = 0; i < m_numIndexes; i++) {
|
||||
GLint elemIndex = appLoc - m_Indexes[i].appBase;
|
||||
if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
|
||||
if (m_Indexes[i].type == GL_TEXTURE_2D) {
|
||||
m_Indexes[i].samplerValue = val;
|
||||
if (target) {
|
||||
if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
|
||||
*target = GL_TEXTURE_EXTERNAL_OES;
|
||||
} else {
|
||||
*target = GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ProgramData::attachShader(GLuint shader)
|
||||
{
|
||||
size_t n = m_shaders.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (m_shaders[i] == shader) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// AKA m_shaders.push_back(), but that has an ambiguous call to insertAt()
|
||||
// due to the default parameters. This is the desired insertAt() overload.
|
||||
m_shaders.insertAt(shader, m_shaders.size(), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProgramData::detachShader(GLuint shader)
|
||||
{
|
||||
size_t n = m_shaders.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (m_shaders[i] == shader) {
|
||||
m_shaders.removeAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/***** GLSharedGroup ****/
|
||||
|
||||
GLSharedGroup::GLSharedGroup() :
|
||||
m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
|
||||
m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
|
||||
m_shaders(android::List<GLuint>())
|
||||
m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -217,13 +306,55 @@ void GLSharedGroup::deleteProgramData(GLuint program)
|
||||
m_programs.removeItem(program);
|
||||
}
|
||||
|
||||
void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type)
|
||||
void GLSharedGroup::attachShader(GLuint program, GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
ProgramData* programData = m_programs.valueFor(program);
|
||||
ssize_t idx = m_shaders.indexOfKey(shader);
|
||||
if (programData && idx >= 0) {
|
||||
if (programData->attachShader(shader)) {
|
||||
refShaderDataLocked(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLSharedGroup::detachShader(GLuint program, GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
ProgramData* programData = m_programs.valueFor(program);
|
||||
ssize_t idx = m_shaders.indexOfKey(shader);
|
||||
if (programData && idx >= 0) {
|
||||
if (programData->detachShader(shader)) {
|
||||
unrefShaderDataLocked(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
ProgramData* pData = m_programs.valueFor(program);
|
||||
if (pData)
|
||||
{
|
||||
pData->setIndexInfo(index,base,size,type);
|
||||
|
||||
if (type == GL_SAMPLER_2D) {
|
||||
size_t n = pData->getNumShaders();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
GLuint shaderId = pData->getShader(i);
|
||||
ShaderData* shader = m_shaders.valueFor(shaderId);
|
||||
if (!shader) continue;
|
||||
ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin();
|
||||
ShaderData::StringList::iterator nameEnd = shader->samplerExternalNames.end();
|
||||
while (nameIter != nameEnd) {
|
||||
if (*nameIter == name) {
|
||||
pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
++nameIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,38 +408,62 @@ bool GLSharedGroup::needUniformLocationWAR(GLuint program)
|
||||
return false;
|
||||
}
|
||||
|
||||
GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
ProgramData* pData = m_programs.valueFor(program);
|
||||
return pData ? pData->getNextSamplerUniform(index, val, target) : -1;
|
||||
}
|
||||
|
||||
void GLSharedGroup::addShaderData(GLuint shader)
|
||||
bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
m_shaders.push_front(shader);
|
||||
|
||||
ProgramData* pData = m_programs.valueFor(program);
|
||||
return pData ? pData->setSamplerUniform(appLoc, val, target) : false;
|
||||
}
|
||||
bool GLSharedGroup::isShader(GLuint shader)
|
||||
|
||||
bool GLSharedGroup::addShaderData(GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
android::List<GLuint>::iterator iter;
|
||||
iter = m_shaders.begin();
|
||||
while (iter!=m_shaders.end())
|
||||
{
|
||||
if (*iter==shader)
|
||||
return true;
|
||||
iter++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void GLSharedGroup::deleteShaderData(GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
android::List<GLuint>::iterator iter;
|
||||
iter = m_shaders.begin();
|
||||
while (iter!=m_shaders.end())
|
||||
{
|
||||
if (*iter==shader)
|
||||
{
|
||||
m_shaders.erase(iter);
|
||||
return;
|
||||
ShaderData* data = new ShaderData;
|
||||
if (data) {
|
||||
if (m_shaders.add(shader, data) < 0) {
|
||||
delete data;
|
||||
data = NULL;
|
||||
}
|
||||
iter++;
|
||||
data->refcount = 1;
|
||||
}
|
||||
return data != NULL;
|
||||
}
|
||||
|
||||
ShaderData* GLSharedGroup::getShaderData(GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
return m_shaders.valueFor(shader);
|
||||
}
|
||||
|
||||
void GLSharedGroup::unrefShaderData(GLuint shader)
|
||||
{
|
||||
android::AutoMutex _lock(m_lock);
|
||||
ssize_t idx = m_shaders.indexOfKey(shader);
|
||||
if (idx >= 0) {
|
||||
unrefShaderDataLocked(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx)
|
||||
{
|
||||
assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
|
||||
ShaderData* data = m_shaders.valueAt(shaderIdx);
|
||||
data->refcount++;
|
||||
}
|
||||
|
||||
void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx)
|
||||
{
|
||||
assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
|
||||
ShaderData* data = m_shaders.valueAt(shaderIdx);
|
||||
if (--data->refcount == 0) {
|
||||
delete data;
|
||||
m_shaders.removeItemsAt(shaderIdx);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user