blob: 232cd9d6c556be5cf963e8f64422bed0b4202d72 [file] [log] [blame]
Stuart Scott4e4502a2013-02-07 14:30:41 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14
15#include <android/native_window.h>
16
17#include <stdlib.h>
18
19#include <EGL/egl.h>
Stuart Scott5e14de92013-07-19 10:26:37 -070020#include <EGL/eglext.h>
Stuart Scott4e4502a2013-02-07 14:30:41 -080021#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
23
24#include "ContextSwitchRenderer.h"
Stuart Scott0163c072013-03-19 13:26:32 -070025#include <graphics/GLUtils.h>
Stuart Scott4e4502a2013-02-07 14:30:41 -080026
Stuart Scott5e14de92013-07-19 10:26:37 -070027#define LOG_TAG "PTS_OPENGL"
28#define LOG_NDEBUG 0
29#include <utils/Log.h>
Stuart Scott0a312e22013-04-03 13:48:08 -070030#include <Trace.h>
Stuart Scott936fe7d2013-02-22 14:03:40 -080031
Stuart Scottc67f78d2013-04-08 13:11:04 -070032static const EGLint contextAttribs[] = {
33 EGL_CONTEXT_CLIENT_VERSION, 2,
34 EGL_NONE };
Stuart Scott4e4502a2013-02-07 14:30:41 -080035
Stuart Scott4d9520f2013-03-25 15:05:36 -070036static const int NUM_WORKER_CONTEXTS = 7;
37
Stuart Scottc67f78d2013-04-08 13:11:04 -070038static const int CS_TEXTURE_SIZE = 64;
39
Stuart Scott0fd2a862013-02-19 10:39:18 -080040static const int CS_NUM_VERTICES = 6;
41
42static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
Stuart Scott4d9520f2013-03-25 15:05:36 -070043 0.1f, 0.1f, -0.1f,
44 -0.1f, 0.1f, -0.1f,
45 -0.1f, -0.1f, -0.1f,
46 -0.1f, -0.1f, -0.1f,
47 0.1f, -0.1f, -0.1f,
48 0.1f, 0.1f, -0.1f };
Stuart Scott0fd2a862013-02-19 10:39:18 -080049
50static const float CS_TEX_COORDS[CS_NUM_VERTICES * 2] = {
Stuart Scott4e4502a2013-02-07 14:30:41 -080051 1.0f, 1.0f,
52 0.0f, 1.0f,
53 0.0f, 0.0f,
54 0.0f, 0.0f,
55 1.0f, 0.0f,
56 1.0f, 1.0f };
57
Stuart Scott0fd2a862013-02-19 10:39:18 -080058static const char* CS_VERTEX =
Stuart Scott4e4502a2013-02-07 14:30:41 -080059 "attribute vec4 a_Position;"
60 "attribute vec2 a_TexCoord;"
Stuart Scott4d9520f2013-03-25 15:05:36 -070061 "uniform float u_Translate;"
Stuart Scott4e4502a2013-02-07 14:30:41 -080062 "varying vec2 v_TexCoord;"
63 "void main() {"
64 " v_TexCoord = a_TexCoord;"
Stuart Scott4d9520f2013-03-25 15:05:36 -070065 " gl_Position.x = a_Position.x + u_Translate;"
Stuart Scott5e14de92013-07-19 10:26:37 -070066 " gl_Position.yzw = a_Position.yzw;"
Stuart Scott4e4502a2013-02-07 14:30:41 -080067 "}";
68
Stuart Scott0fd2a862013-02-19 10:39:18 -080069static const char* CS_FRAGMENT =
Stuart Scott4e4502a2013-02-07 14:30:41 -080070 "precision mediump float;"
71 "uniform sampler2D u_Texture;"
72 "varying vec2 v_TexCoord;"
73 "void main() {"
74 " gl_FragColor = texture2D(u_Texture, v_TexCoord);"
75 "}";
76
Stuart Scottcb2e0a92013-02-27 10:27:15 -080077ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen, int workload) :
78 Renderer(window, offscreen, workload), mContexts(NULL) {
Stuart Scott4e4502a2013-02-07 14:30:41 -080079}
80
81bool ContextSwitchRenderer::setUp() {
Stuart Scott4d9520f2013-03-25 15:05:36 -070082 SCOPED_TRACE();
Stuart Scott4e4502a2013-02-07 14:30:41 -080083 if (!Renderer::setUp()) {
84 return false;
85 }
86
Stuart Scott4d9520f2013-03-25 15:05:36 -070087 // Setup texture.
Stuart Scottc67f78d2013-04-08 13:11:04 -070088 mTextureId = GLUtils::genTexture(CS_TEXTURE_SIZE, CS_TEXTURE_SIZE, GLUtils::RANDOM_FILL);
Stuart Scott4d9520f2013-03-25 15:05:36 -070089 if (mTextureId == 0) {
90 return false;
Stuart Scottcb2e0a92013-02-27 10:27:15 -080091 }
Stuart Scott4d9520f2013-03-25 15:05:36 -070092
93 // Create program.
94 mProgramId = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
95 if (mProgramId == 0) {
96 return false;
97 }
98 // Bind attributes.
99 mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
100 mTranslateUniformHandle = glGetUniformLocation(mProgramId, "u_Translate");
101 mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
102 mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
103
104 mContexts = new EGLContext[NUM_WORKER_CONTEXTS];
Stuart Scott5e14de92013-07-19 10:26:37 -0700105 mFboIds = new GLuint[NUM_WORKER_CONTEXTS];
Stuart Scott4d9520f2013-03-25 15:05:36 -0700106 for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
107 // Create the contexts, they share data with the main one.
108 mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, mEglContext, contextAttribs);
Stuart Scott4e4502a2013-02-07 14:30:41 -0800109 if (EGL_NO_CONTEXT == mContexts[i] || EGL_SUCCESS != eglGetError()) {
110 return false;
111 }
112
113 if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
114 || EGL_SUCCESS != eglGetError()) {
115 return false;
116 }
Stuart Scott5e14de92013-07-19 10:26:37 -0700117 if (mOffscreen) {
118 // FBOs are not shared across contexts, textures and renderbuffers are though.
119 glGenFramebuffers(1, &mFboIds[i]);
120 glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
Stuart Scott4e4502a2013-02-07 14:30:41 -0800121
Stuart Scott5e14de92013-07-19 10:26:37 -0700122 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
123 GL_RENDERBUFFER, mFboDepthId);
124
125 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
126 GL_TEXTURE_2D, mFboTexId, 0);
127 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
128 if (status != GL_FRAMEBUFFER_COMPLETE) {
129 ALOGE("Framebuffer not complete: %d", status);
130 return false;
131 }
132 }
133 }
Stuart Scott4e4502a2013-02-07 14:30:41 -0800134 return true;
135}
136
137bool ContextSwitchRenderer::tearDown() {
Stuart Scott4d9520f2013-03-25 15:05:36 -0700138 SCOPED_TRACE();
Stuart Scott4e4502a2013-02-07 14:30:41 -0800139 if (mContexts) {
Stuart Scott4d9520f2013-03-25 15:05:36 -0700140 // Destroy the contexts, the main one will be handled by Renderer::tearDown().
141 for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
Stuart Scott5e14de92013-07-19 10:26:37 -0700142 if (mOffscreen) {
143 if (mFboIds[i] != 0) {
144 eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
145 glDeleteFramebuffers(1, &mFboIds[i]);
146 mFboIds[i] = 0;
147 }
148 }
Stuart Scott4e4502a2013-02-07 14:30:41 -0800149 eglDestroyContext(mEglDisplay, mContexts[i]);
150 }
151 delete[] mContexts;
152 }
Stuart Scott5e14de92013-07-19 10:26:37 -0700153 eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700154 if (mTextureId != 0) {
155 glDeleteTextures(1, &mTextureId);
156 mTextureId = 0;
Stuart Scott4e4502a2013-02-07 14:30:41 -0800157 }
158 if (!Renderer::tearDown()) {
159 return false;
160 }
161 return true;
162}
163
Stuart Scott5e14de92013-07-19 10:26:37 -0700164void ContextSwitchRenderer::drawWorkload() {
Stuart Scott4d9520f2013-03-25 15:05:36 -0700165 SCOPED_TRACE();
Stuart Scott4d9520f2013-03-25 15:05:36 -0700166 // Set the background clear color to black.
167 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
168 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
169 // No culling of back faces
170 glDisable(GL_CULL_FACE);
171 // No depth testing
172 glDisable(GL_DEPTH_TEST);
173
Stuart Scott5e14de92013-07-19 10:26:37 -0700174 EGLSyncKHR fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
175
Stuart Scott4d9520f2013-03-25 15:05:36 -0700176 const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
177 const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
178 for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
Stuart Scott5e14de92013-07-19 10:26:37 -0700179 eglWaitSyncKHR(mEglDisplay, fence, 0);
180 eglDestroySyncKHR(mEglDisplay, fence);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700181 glUseProgram(mProgramId);
182
Stuart Scott5e14de92013-07-19 10:26:37 -0700183 // Set the texture.
Stuart Scott4d9520f2013-03-25 15:05:36 -0700184 glActiveTexture (GL_TEXTURE0);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700185 glBindTexture(GL_TEXTURE_2D, mTextureId);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700186 glUniform1i(mTextureUniformHandle, 0);
187
188 // Set the x translate.
189 glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);
190
191 glEnableVertexAttribArray(mPositionHandle);
192 glEnableVertexAttribArray(mTexCoordHandle);
193 glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
194 glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
195
196 glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
Stuart Scott5e14de92013-07-19 10:26:37 -0700197 fence = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_FENCE_KHR, NULL);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700198
199 // Switch to next context.
200 if (i < (mWorkload - 1)) {
Stuart Scott5e14de92013-07-19 10:26:37 -0700201 eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i]);
202 // Switch to FBO and re-attach.
203 if (mOffscreen) {
204 glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
205 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
206 GL_RENDERBUFFER, mFboDepthId);
207 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
208 GL_TEXTURE_2D, mFboTexId, 0);
209 glViewport(0, 0, mFboWidth, mFboHeight);
Stuart Scott4d9520f2013-03-25 15:05:36 -0700210 }
211 }
Stuart Scott5e14de92013-07-19 10:26:37 -0700212 GLuint err = glGetError();
213 if (err != GL_NO_ERROR) {
214 ALOGE("GLError %d in drawWorkload", err);
215 break;
Stuart Scott4d9520f2013-03-25 15:05:36 -0700216 }
217 }
218
Stuart Scott5e14de92013-07-19 10:26:37 -0700219 // Switch back to the main context.
220 eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
221 if (mOffscreen) {
222 glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
223 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
224 GL_RENDERBUFFER, mFboDepthId);
225 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
226 GL_TEXTURE_2D, mFboTexId, 0);
227 glViewport(0, 0, mFboWidth, mFboHeight);
228 }
Stuart Scott4e4502a2013-02-07 14:30:41 -0800229}