rsdShaderCache.cpp revision c460e55d78cbe8bee95c5c947dfe541218142a5b
1c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams/* 2c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * Copyright (C) 2009 The Android Open Source Project 3c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * 4c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * you may not use this file except in compliance with the License. 6c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * You may obtain a copy of the License at 7c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * 8c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * http://www.apache.org/licenses/LICENSE-2.0 9c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * 10c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * Unless required by applicable law or agreed to in writing, software 11c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * See the License for the specific language governing permissions and 14c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams * limitations under the License. 15c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams */ 16c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 17c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include "rsContext.h" 18c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 19c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES/gl.h> 20c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams#include <GLES2/gl2.h> 21c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 22c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsusing namespace android; 23c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsusing namespace android::renderscript; 24c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 25c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 26c460e55d78cbe8bee95c5c947dfe541218142a5bJason SamsShaderCache::ShaderCache() 27c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 28c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryCount = 0; 29c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryAllocationCount = 16; 30c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntries = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); 31c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 32c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 33c460e55d78cbe8bee95c5c947dfe541218142a5bJason SamsShaderCache::~ShaderCache() 34c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 35c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < mEntryCount; ct++) { 36c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glDeleteProgram(mEntries[ct].program); 37c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 38c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 39c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryCount = 0; 40c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryAllocationCount = 0; 41c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams free(mEntries); 42c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 43c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 44c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsbool ShaderCache::lookup(ProgramVertex *vtx, ProgramFragment *frag) 45c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 46c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!vtx->getShaderID()) { 47c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams vtx->loadShader(); 48c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 49c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!frag->getShaderID()) { 50c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams frag->loadShader(); 51c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 52c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 53c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < mEntryCount; ct++) { 54c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if ((mEntries[ct].vtx == vtx->getShaderID()) && 55c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams (mEntries[ct].frag == frag->getShaderID())) { 56c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 57c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGV("SC using program %i", mEntries[ct].program); 58c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glUseProgram(mEntries[ct].program); 59c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mCurrent = &mEntries[ct]; 60c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return true; 61c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 62c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 63c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams // Not in cache, add it. 64c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 65c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (mEntryAllocationCount == mEntryCount) { 66c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams // Out of space, make some. 67c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryAllocationCount *= 2; 68c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); 69c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!e) { 70c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGE("Out of memory for ShaderCache::lookup"); 71c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return false; 72c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 73c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); 74c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams free(mEntries); 75c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntries = e; 76c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 77c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 78c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGV("vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); 79c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGE("e0 %x", glGetError()); 80c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 81c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams entry_t *e = &mEntries[mEntryCount]; 82c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mCurrent = e; 83c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->vtx = vtx->getShaderID(); 84c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->frag = frag->getShaderID(); 85c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->program = glCreateProgram(); 86c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (mEntries[mEntryCount].program) { 87c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLuint pgm = e->program; 88c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glAttachShader(pgm, vtx->getShaderID()); 89c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e1 %x", glGetError()); 90c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glAttachShader(pgm, frag->getShaderID()); 91c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 92c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glBindAttribLocation(pgm, VertexArray::POSITION, "attrib_Position"); 93c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glBindAttribLocation(pgm, VertexArray::COLOR, "attrib_Color"); 94c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 95c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 96c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e2 %x", glGetError()); 97c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glLinkProgram(pgm); 98c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e3 %x", glGetError()); 99c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLint linkStatus = GL_FALSE; 100c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus); 101c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (linkStatus != GL_TRUE) { 102c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLint bufLength = 0; 103c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength); 104c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (bufLength) { 105c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams char* buf = (char*) malloc(bufLength); 106c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (buf) { 107c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramInfoLog(pgm, bufLength, NULL, buf); 108c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGE("Could not link program:\n%s\n", buf); 109c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams free(buf); 110c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 111c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 112c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glDeleteProgram(pgm); 113c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 114c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) { 115c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); 116c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGV("vtx A, %s = %d\n", vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); 117c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 118c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { 119c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct)); 120c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]); 121c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 122c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { 123c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct)); 124c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]); 125c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 126c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 127c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 128c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGV("SC made program %i", e->program); 129c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glUseProgram(e->program); 130c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryCount++; 131c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return true; 132c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 133c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 134c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupVertex(uint32_t id) 135c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 136c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 137c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 138c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupFragment(uint32_t id) 139c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 140c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 141c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 142c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupAll() 143c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 144c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 145c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 146