rsdShaderCache.cpp revision cd50653f99c960e1a47c2c30e53b369b8805344a
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 44cd50653f99c960e1a47c2c30e53b369b8805344aJason Samsbool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag) 45c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 46c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!vtx->getShaderID()) { 47cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams vtx->loadShader(rsc); 48c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 49c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!frag->getShaderID()) { 50cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams frag->loadShader(rsc); 51c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 52f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams //LOGV("ShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID()); 53c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 54c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < mEntryCount; ct++) { 55c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if ((mEntries[ct].vtx == vtx->getShaderID()) && 56c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams (mEntries[ct].frag == frag->getShaderID())) { 57c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 58c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGV("SC using program %i", mEntries[ct].program); 59c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glUseProgram(mEntries[ct].program); 60c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mCurrent = &mEntries[ct]; 61f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams //LOGV("ShaderCache hit, using %i", ct); 62c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return true; 63c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 64c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 65c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams // Not in cache, add it. 66c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 67c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (mEntryAllocationCount == mEntryCount) { 68c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams // Out of space, make some. 69c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryAllocationCount *= 2; 70c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams entry_t *e = (entry_t *)calloc(mEntryAllocationCount, sizeof(entry_t)); 71c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (!e) { 72c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGE("Out of memory for ShaderCache::lookup"); 73c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return false; 74c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 75c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams memcpy(e, mEntries, sizeof(entry_t) * mEntryCount); 76c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams free(mEntries); 77c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntries = e; 78c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 79c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 80f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams //LOGV("ShaderCache miss, using %i", mEntryCount); 81f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams //LOGE("e0 %x", glGetError()); 82c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 83c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams entry_t *e = &mEntries[mEntryCount]; 84c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mCurrent = e; 85c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->vtx = vtx->getShaderID(); 86c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->frag = frag->getShaderID(); 87c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->program = glCreateProgram(); 88c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (mEntries[mEntryCount].program) { 89c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLuint pgm = e->program; 90c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glAttachShader(pgm, vtx->getShaderID()); 91c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e1 %x", glGetError()); 92c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glAttachShader(pgm, frag->getShaderID()); 93c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 94c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glBindAttribLocation(pgm, VertexArray::POSITION, "attrib_Position"); 95c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glBindAttribLocation(pgm, VertexArray::COLOR, "attrib_Color"); 96c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 97c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 98c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e2 %x", glGetError()); 99c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glLinkProgram(pgm); 100c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams //LOGE("e3 %x", glGetError()); 101c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLint linkStatus = GL_FALSE; 102c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramiv(pgm, GL_LINK_STATUS, &linkStatus); 103c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (linkStatus != GL_TRUE) { 104c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams GLint bufLength = 0; 105c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &bufLength); 106c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (bufLength) { 107c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams char* buf = (char*) malloc(bufLength); 108c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams if (buf) { 109c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glGetProgramInfoLog(pgm, bufLength, NULL, buf); 110c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams LOGE("Could not link program:\n%s\n", buf); 111c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams free(buf); 112c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 113c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 114c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glDeleteProgram(pgm); 115c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 116c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getAttribCount(); ct++) { 117c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mVtxAttribSlots[ct] = glGetAttribLocation(pgm, vtx->getAttribName(ct)); 118cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams if (rsc->props.mLogShaders) { 119cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams LOGV("vtx A, %s = %d\n", vtx->getAttribName(ct).string(), e->mVtxAttribSlots[ct]); 120cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams } 121c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 122c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { 123c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mVtxUniformSlots[ct] = glGetUniformLocation(pgm, vtx->getUniformName(ct)); 124cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams if (rsc->props.mLogShaders) { 125cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]); 126cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams } 127c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 128c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) { 129c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct)); 130cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams if (rsc->props.mLogShaders) { 131cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]); 132cd50653f99c960e1a47c2c30e53b369b8805344aJason Sams } 133c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 134c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams } 135c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 136f2a5d7326b38e5a28b6618f9b1e5a021aef7179fJason Sams //LOGV("SC made program %i", e->program); 137c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams glUseProgram(e->program); 138c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams mEntryCount++; 139c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams return true; 140c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 141c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 142c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupVertex(uint32_t id) 143c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 144c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 145c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 146c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupFragment(uint32_t id) 147c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 148c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 149c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 150c460e55d78cbe8bee95c5c947dfe541218142a5bJason Samsvoid ShaderCache::cleanupAll() 151c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams{ 152c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams} 153c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams 154