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