7a5205665c7574c347964e3946ce08ffa5b15bef
[glmemperf] / shaderblittest.cpp
1 /**
2  * OpenGL ES 2.0 memory performance estimator
3  * Copyright (C) 2009 Nokia
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * \author Sami Kyöstilä <sami.kyostila@nokia.com>
20  *
21  * Shader blit test
22  */
23 #include "shaderblittest.h"
24 #include <sstream>
25 #include <GLES2/gl2ext.h>
26
27 ShaderBlitTest::ShaderBlitTest(const std::string& effect, int width, int height, 
28                                float texW, float texH,
29                                float quadW, float quadH):
30     m_width(width),
31     m_height(height),
32     m_texW(texW),
33     m_texH(texH),
34     m_quadW(quadW),
35     m_quadH(quadH),
36     m_effect(effect)
37 {
38 }
39
40 void ShaderBlitTest::teardown()
41 {
42     glUseProgram(0);
43     glDisableVertexAttribArray(m_positionAttr);
44     glDisableVertexAttribArray(m_texcoordAttr);
45     glDeleteProgram(m_program);
46     // Disabled until driver segfault is fixed
47     //glDeleteTextures(1, &m_texture);
48 }
49
50 void ShaderBlitTest::operator()(int frame)
51 {
52     float t = frame * 0;
53
54     const GLfloat texcoords[] =
55     {
56          0 + t,       m_texH + t,
57          0 + t,       0 + t,
58          m_texW + t,  m_texH + t,
59          m_texW + t,  0 + t
60     };
61
62     const GLfloat vertices[] =
63     {
64         -m_quadW, -m_quadH,
65         -m_quadW,  m_quadH,
66          m_quadW, -m_quadH,
67          m_quadW,  m_quadH
68     };
69
70     glVertexAttribPointer(m_positionAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
71     glVertexAttribPointer(m_texcoordAttr, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
72     glClear(GL_COLOR_BUFFER_BIT);
73     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
74 }
75
76 std::string ShaderBlitTest::name() const
77 {
78     std::stringstream s;
79
80     s << "blit_shader_" << m_effect;
81     s << "_" << m_width << "x" << m_height;
82
83     return s.str();
84 }
85
86 void ShaderBlitTest::prepare()
87 {
88     const char* vertSource = 
89         "precision mediump float;\n"
90         "attribute vec2 in_position;\n"
91         "attribute vec2 in_texcoord;\n"
92         "varying vec2 texcoord;\n"
93         "\n"
94         "void main()\n"
95         "{\n"
96         "       gl_Position = vec4(in_position, 0.0, 1.0);\n"
97         "       texcoord = in_texcoord;\n"
98         "}\n";
99
100     const char* fragSourceConst = 
101         "precision lowp float;\n"
102         "\n"
103         "void main()\n"
104         "{\n"
105         "       gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
106         "}\n";
107
108     const char* fragSourceLinGrad = 
109         "precision lowp float;\n"
110         "varying vec2 texcoord;\n"
111         "\n"
112         "void main()\n"
113         "{\n"
114         "       gl_FragColor = vec4(texcoord.x, 0.0, 0.0, 1.0);\n"
115         "}\n";
116
117     const char* fragSourceRadGrad = 
118         "precision mediump float;\n"
119         "varying vec2 texcoord;\n"
120         "\n"
121         "void main()\n"
122         "{\n"
123         "   float t = 1.0 - distance(texcoord, vec2(0.5, 0.5)) * 2.0;\n"
124         "       gl_FragColor = vec4(0.0, t, 0.0, 1.0);\n"
125         "}\n";
126
127     const char* fragSourcePalette = 
128         "precision mediump float;\n"
129         "varying vec2 texcoord;\n"
130         "uniform sampler2D texture;\n"
131         "uniform sampler2D paletteTexture;\n"
132         "\n"
133         "void main()\n"
134         "{\n"
135         "       float index = texture2D(texture, texcoord).a;\n"
136         "       gl_FragColor = texture2D(paletteTexture, vec2(index, 0.0));\n"
137         "}\n";
138
139     const char* fragSourceMask = 
140         "precision mediump float;\n"
141         "varying vec2 texcoord;\n"
142         "uniform sampler2D texture;\n"
143         "\n"
144         "void main()\n"
145         "{\n"
146         "       float mask   = texture2D(texture, texcoord).g;\n"
147         "       vec4 color   = texture2D(texture, texcoord + vec2(0, 64.0 / 128.0));\n"
148         "       gl_FragColor = vec4(color.rgb, mask);\n"
149         "}\n";
150
151     const char* fragSource = 0;
152     if (m_effect == "const")
153     {
154         fragSource = fragSourceConst;
155     }
156     else if (m_effect == "lingrad")
157     {
158         fragSource = fragSourceLinGrad;
159     }
160     else if (m_effect == "radgrad")
161     {
162         fragSource = fragSourceRadGrad;
163     }
164     else if (m_effect == "palette")
165     {
166         fragSource = fragSourcePalette;
167     }
168     else if (m_effect == "mask")
169     {
170         fragSource = fragSourceMask;
171     }
172     assert(fragSource);
173
174     m_program = createProgram(vertSource, fragSource);
175     glUseProgram(m_program);
176
177     glClearColor(.2, .4, .6, 1.0);
178
179     m_positionAttr = glGetAttribLocation(m_program, "in_position");
180     m_texcoordAttr = glGetAttribLocation(m_program, "in_texcoord");
181
182     glGenTextures(1, &m_texture);
183     glEnableVertexAttribArray(m_positionAttr);
184     glEnableVertexAttribArray(m_texcoordAttr);
185
186     if (m_effect == "palette")
187     {
188         char* texture = new char[800 * 480];
189         char* palette = new char[256 * 4];
190         for (int y = 0; y < 480; y++)
191         {
192             for (int x = 0; x < 800; x++)
193             {
194                 texture[y * 800 + x] = x ^ y;
195             }
196         }
197         for (int i = 0; i < 256; i++)
198         {
199             palette[i * 4 + 0] = i;
200             palette[i * 4 + 1] = abs(i - 0x7f);
201             palette[i * 4 + 2] = 0xff - i;
202             palette[i * 4 + 3] = 0xff;
203         }
204         glActiveTexture(GL_TEXTURE1);
205         glBindTexture(GL_TEXTURE_2D, 3);
206         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, palette);
207         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
208         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
209         ASSERT_GL();
210         glActiveTexture(GL_TEXTURE0);
211         glBindTexture(GL_TEXTURE_2D, 4);
212         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 800, 480, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture);
213         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
214         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
215         ASSERT_GL();
216         delete[] texture;
217         delete[] palette;
218         glUniform1i(glGetUniformLocation(m_program, "texture"), 0);
219         glUniform1i(glGetUniformLocation(m_program, "paletteTexture"), 1);
220         ASSERT_GL();
221     }
222
223     if (m_effect == "mask")
224     {
225         glBindTexture(GL_TEXTURE_2D, m_texture);
226         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
227         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
228         loadCompressedTexture(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, 128, 256, "data/xorg-colormask_128x256_etc1.raw");
229         glUniform1i(glGetUniformLocation(m_program, "texture"), 0);
230         ASSERT_GL();
231     }
232
233     ASSERT_GL();
234 }