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