1 /* 2 * Copyright (C) 2019 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 package android.gameperformance; 17 18 import java.util.List; 19 20 import javax.microedition.khronos.opengles.GL; 21 22 import android.annotation.NonNull; 23 import android.content.Context; 24 import android.opengl.GLES20; 25 import android.opengl.Matrix; 26 27 /** 28 * Base class for all OpenGL based tests that use RenderPatch as a base. 29 */ 30 public abstract class RenderPatchOpenGLTest extends OpenGLTest { 31 private final float[] COLOR = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; 32 33 private final String VERTEX_SHADER = 34 "uniform mat4 uMVPMatrix;" 35 + "attribute vec4 vPosition;" 36 + "attribute vec2 vTexture;" 37 + "varying vec2 vTex;" 38 + "void main() {" 39 + " vTex = vTexture;" 40 + " gl_Position = uMVPMatrix * vPosition;" 41 + "}"; 42 43 private final String FRAGMENT_SHADER = 44 "precision mediump float;" 45 + "uniform sampler2D uTexture;" 46 + "uniform vec4 uColor;" 47 + "varying vec2 vTex;" 48 + "void main() {" 49 + " vec4 color = texture2D(uTexture, vTex);" 50 + " gl_FragColor = uColor * color;" 51 + "}"; 52 53 private List<RenderPatchAnimation> mRenderPatches; 54 55 private int mProgram = -1; 56 private int mMVPMatrixHandle; 57 private int mTextureHandle; 58 private int mPositionHandle; 59 private int mColorHandle; 60 private int mTextureCoordHandle; 61 62 private final float[] mVPMatrix = new float[16]; 63 RenderPatchOpenGLTest(@onNull GamePerformanceActivity activity)64 public RenderPatchOpenGLTest(@NonNull GamePerformanceActivity activity) { 65 super(activity); 66 } 67 setRenderPatches(@onNull List<RenderPatchAnimation> renderPatches)68 protected void setRenderPatches(@NonNull List<RenderPatchAnimation> renderPatches) { 69 mRenderPatches = renderPatches; 70 } 71 ensureInited()72 private void ensureInited() { 73 if (mProgram >= 0) { 74 return; 75 } 76 77 mProgram = OpenGLUtils.createProgram(VERTEX_SHADER, FRAGMENT_SHADER); 78 79 // get handle to fragment shader's uColor member 80 GLES20.glUseProgram(mProgram); 81 OpenGLUtils.checkGlError("useProgram"); 82 83 // get handle to shape's transformation matrix 84 mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 85 OpenGLUtils.checkGlError("get uMVPMatrix"); 86 87 mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture"); 88 OpenGLUtils.checkGlError("uTexture"); 89 // get handle to vertex shader's vPosition member 90 mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 91 OpenGLUtils.checkGlError("vPosition"); 92 mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "vTexture"); 93 OpenGLUtils.checkGlError("vTexture"); 94 mColorHandle = GLES20.glGetUniformLocation(mProgram, "uColor"); 95 OpenGLUtils.checkGlError("uColor"); 96 97 mTextureHandle = OpenGLUtils.createTexture(getContext(), R.drawable.logo); 98 99 final float[] projectionMatrix = new float[16]; 100 final float[] viewMatrix = new float[16]; 101 102 final float ratio = getView().getRenderRatio(); 103 Matrix.orthoM(projectionMatrix, 0, -ratio, ratio, -1, 1, -1, 1); 104 Matrix.setLookAtM(viewMatrix, 0, 0, 0, -0.5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 105 Matrix.multiplyMM(mVPMatrix, 0, projectionMatrix, 0, viewMatrix, 0); 106 } 107 108 /** 109 * Returns global color for patch. 110 */ getColor()111 public float[] getColor() { 112 return COLOR; 113 } 114 115 /** 116 * Extra setup for particular tests. 117 */ onBeforeDraw(GL gl)118 public void onBeforeDraw(GL gl) { 119 } 120 121 @Override draw(GL gl)122 public void draw(GL gl) { 123 ensureInited(); 124 125 GLES20.glUseProgram(mProgram); 126 OpenGLUtils.checkGlError("useProgram"); 127 128 GLES20.glDisable(GLES20.GL_BLEND); 129 OpenGLUtils.checkGlError("disableBlend"); 130 131 GLES20.glEnableVertexAttribArray(mPositionHandle); 132 OpenGLUtils.checkGlError("enableVertexAttributes"); 133 134 GLES20.glEnableVertexAttribArray(mTextureCoordHandle); 135 OpenGLUtils.checkGlError("enableTexturesAttributes"); 136 137 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle); 138 OpenGLUtils.checkGlError("setTexture"); 139 140 GLES20.glUniform4fv(mColorHandle, 1, getColor(), 0); 141 OpenGLUtils.checkGlError("setColor"); 142 143 onBeforeDraw(gl); 144 145 for (final RenderPatchAnimation renderPatchAnimation : mRenderPatches) { 146 147 renderPatchAnimation.update(0.01f); 148 GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 149 1, 150 false, 151 renderPatchAnimation.getTransform(mVPMatrix), 152 0); 153 OpenGLUtils.checkGlError("setTransform"); 154 155 GLES20.glVertexAttribPointer( 156 mPositionHandle, 157 RenderPatch.VERTEX_COORD_COUNT, 158 GLES20.GL_FLOAT, 159 false /* normalized */, 160 RenderPatch.VERTEX_STRIDE, 161 renderPatchAnimation.getRenderPatch().getVertexBuffer()); 162 OpenGLUtils.checkGlError("setVertexAttribute"); 163 164 GLES20.glVertexAttribPointer( 165 mTextureCoordHandle, 166 RenderPatch.TEXTURE_COORD_COUNT, 167 GLES20.GL_FLOAT, 168 false /* normalized */, 169 RenderPatch.TEXTURE_STRIDE, 170 renderPatchAnimation.getRenderPatch().getTextureBuffer()); 171 OpenGLUtils.checkGlError("setTextureAttribute"); 172 173 // Draw the patch. 174 final int indicesCount = 175 renderPatchAnimation.getRenderPatch().getIndexBuffer().capacity() / 176 RenderPatch.SHORT_SIZE; 177 GLES20.glDrawElements( 178 GLES20.GL_TRIANGLES, 179 indicesCount, 180 GLES20.GL_UNSIGNED_SHORT, 181 renderPatchAnimation.getRenderPatch().getIndexBuffer()); 182 OpenGLUtils.checkGlError("drawPatch"); 183 } 184 185 GLES20.glDisableVertexAttribArray(mPositionHandle); 186 GLES20.glDisableVertexAttribArray(mTextureCoordHandle); 187 } 188 }