1 //
2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "TexSubImage.h"
8
9 #include <sstream>
10 #include <cassert>
11
12 #include "shader_utils.h"
13
name() const14 std::string TexSubImageParams::name() const
15 {
16 std::stringstream strstr;
17
18 strstr << "TexSubImage - " << BenchmarkParams::name()
19 << " - " << imageWidth << "x" << imageHeight
20 << " - " << subImageWidth << "x" << subImageHeight << " updates";
21
22 return strstr.str();
23 }
24
TexSubImageBenchmark(const TexSubImageParams & params)25 TexSubImageBenchmark::TexSubImageBenchmark(const TexSubImageParams ¶ms)
26 : SimpleBenchmark(params.name(), 512, 512, 2, params.requestedRenderer),
27 mParams(params),
28 mProgram(0),
29 mPositionLoc(-1),
30 mTexCoordLoc(-1),
31 mSamplerLoc(-1),
32 mTexture(0),
33 mVertexBuffer(0),
34 mIndexBuffer(0),
35 mPixels(NULL)
36 {
37 assert(mParams.iterations > 0);
38 mDrawIterations = mParams.iterations;
39 }
40
createTexture()41 GLuint TexSubImageBenchmark::createTexture()
42 {
43 // Use tightly packed data
44 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
45
46 // Generate a texture object
47 GLuint texture;
48 glGenTextures(1, &texture);
49
50 // Bind the texture object
51 glBindTexture(GL_TEXTURE_2D, texture);
52
53 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, mParams.imageWidth, mParams.imageHeight);
54
55 // Set the filtering mode
56 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
58
59 return texture;
60 }
61
initializeBenchmark()62 bool TexSubImageBenchmark::initializeBenchmark()
63 {
64 const std::string vs = SHADER_SOURCE
65 (
66 attribute vec4 a_position;
67 attribute vec2 a_texCoord;
68 varying vec2 v_texCoord;
69 void main()
70 {
71 gl_Position = a_position;
72 v_texCoord = a_texCoord;
73 }
74 );
75
76 const std::string fs = SHADER_SOURCE
77 (
78 precision mediump float;
79 varying vec2 v_texCoord;
80 uniform sampler2D s_texture;
81 void main()
82 {
83 gl_FragColor = texture2D(s_texture, v_texCoord);
84 }
85 );
86
87 mProgram = CompileProgram(vs, fs);
88 if (!mProgram)
89 {
90 return false;
91 }
92
93 // Get the attribute locations
94 mPositionLoc = glGetAttribLocation(mProgram, "a_position");
95 mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
96
97 // Get the sampler location
98 mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
99
100 // Build the vertex buffer
101 GLfloat vertices[] =
102 {
103 -0.5f, 0.5f, 0.0f, // Position 0
104 0.0f, 0.0f, // TexCoord 0
105 -0.5f, -0.5f, 0.0f, // Position 1
106 0.0f, 1.0f, // TexCoord 1
107 0.5f, -0.5f, 0.0f, // Position 2
108 1.0f, 1.0f, // TexCoord 2
109 0.5f, 0.5f, 0.0f, // Position 3
110 1.0f, 0.0f // TexCoord 3
111 };
112
113 glGenBuffers(1, &mVertexBuffer);
114 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
115 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
116
117 GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
118 glGenBuffers(1, &mIndexBuffer);
119 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
120 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
121
122 // Load the texture
123 mTexture = createTexture();
124
125 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
126
127 mPixels = new GLubyte[mParams.subImageWidth * mParams.subImageHeight * 4];
128
129 // Fill the pixels structure with random data:
130 for (int y = 0; y < mParams.subImageHeight; ++y)
131 {
132 for (int x = 0; x < mParams.subImageWidth; ++x)
133 {
134 int offset = (x + (y * mParams.subImageWidth)) * 4;
135 mPixels[offset + 0] = rand() % 255; // Red
136 mPixels[offset + 1] = rand() % 255; // Green
137 mPixels[offset + 2] = rand() % 255; // Blue
138 mPixels[offset + 3] = 255; // Alpha
139 }
140 }
141
142 return true;
143 }
144
destroyBenchmark()145 void TexSubImageBenchmark::destroyBenchmark()
146 {
147 glDeleteProgram(mProgram);
148 glDeleteBuffers(1, &mVertexBuffer);
149 glDeleteBuffers(1, &mIndexBuffer);
150 glDeleteTextures(1, &mTexture);
151 delete[] mPixels;
152 }
153
beginDrawBenchmark()154 void TexSubImageBenchmark::beginDrawBenchmark()
155 {
156 // Set the viewport
157 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
158
159 // Clear the color buffer
160 glClear(GL_COLOR_BUFFER_BIT);
161
162 // Use the program object
163 glUseProgram(mProgram);
164
165 // Bind the buffers
166 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
167 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
168
169 // Load the vertex position
170 glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
171 // Load the texture coordinate
172 glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
173
174 glEnableVertexAttribArray(mPositionLoc);
175 glEnableVertexAttribArray(mTexCoordLoc);
176
177 // Bind the texture
178 glActiveTexture(GL_TEXTURE0);
179 glBindTexture(GL_TEXTURE_2D, mTexture);
180
181 // Set the texture sampler to texture unit to 0
182 glUniform1i(mSamplerLoc, 0);
183 }
184
drawBenchmark()185 void TexSubImageBenchmark::drawBenchmark()
186 {
187 glTexSubImage2D(GL_TEXTURE_2D, 0,
188 rand() % (mParams.imageWidth - mParams.subImageWidth),
189 rand() % (mParams.imageHeight - mParams.subImageHeight),
190 mParams.subImageWidth, mParams.subImageHeight,
191 GL_RGBA, GL_UNSIGNED_BYTE, mPixels);
192
193 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
194 }
195