flatland: add a GPU hardware benchmark
This change adds a GPU benchmark named 'flatland' that is intended to measure
GPU performance of UI rendering and compositing scenarios at a fixed a clock
frequency. This initial version includes only window compositing scenarios.
Change-Id: I5577863aa3be5c6da8b49cb5d53cc49dec2f7081
diff --git a/cmds/flatland/Composers.cpp b/cmds/flatland/Composers.cpp
new file mode 100644
index 0000000..8365a31
--- /dev/null
+++ b/cmds/flatland/Composers.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Flatland.h"
+#include "GLHelper.h"
+
+namespace android {
+
+class Blitter {
+public:
+
+ bool setUp(GLHelper* helper) {
+ bool result;
+
+ result = helper->getShaderProgram("Blit", &mBlitPgm);
+ if (!result) {
+ return false;
+ }
+
+ mPosAttribLoc = glGetAttribLocation(mBlitPgm, "position");
+ mUVAttribLoc = glGetAttribLocation(mBlitPgm, "uv");
+ mUVToTexUniformLoc = glGetUniformLocation(mBlitPgm, "uvToTex");
+ mObjToNdcUniformLoc = glGetUniformLocation(mBlitPgm, "objToNdc");
+ mBlitSrcSamplerLoc = glGetUniformLocation(mBlitPgm, "blitSrc");
+ mModColorUniformLoc = glGetUniformLocation(mBlitPgm, "modColor");
+
+ return true;
+ }
+
+ bool blit(GLuint texName, const float* texMatrix,
+ int32_t x, int32_t y, uint32_t w, uint32_t h) {
+ float modColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ return modBlit(texName, texMatrix, modColor, x, y, w, h);
+ }
+
+ bool modBlit(GLuint texName, const float* texMatrix, float* modColor,
+ int32_t x, int32_t y, uint32_t w, uint32_t h) {
+ glUseProgram(mBlitPgm);
+
+ GLint vp[4];
+ glGetIntegerv(GL_VIEWPORT, vp);
+ float screenToNdc[16] = {
+ 2.0f/float(vp[2]), 0.0f, 0.0f, 0.0f,
+ 0.0f, -2.0f/float(vp[3]), 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 1.0f,
+ };
+ const float pos[] = {
+ float(x), float(y),
+ float(x+w), float(y),
+ float(x), float(y+h),
+ float(x+w), float(y+h),
+ };
+ const float uv[] = {
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ };
+
+ glVertexAttribPointer(mPosAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, pos);
+ glVertexAttribPointer(mUVAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, uv);
+ glEnableVertexAttribArray(mPosAttribLoc);
+ glEnableVertexAttribArray(mUVAttribLoc);
+
+ glUniformMatrix4fv(mObjToNdcUniformLoc, 1, GL_FALSE, screenToNdc);
+ glUniformMatrix4fv(mUVToTexUniformLoc, 1, GL_FALSE, texMatrix);
+ glUniform4fv(mModColorUniformLoc, 1, modColor);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName);
+ glUniform1i(mBlitSrcSamplerLoc, 0);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableVertexAttribArray(mPosAttribLoc);
+ glDisableVertexAttribArray(mUVAttribLoc);
+
+ if (glGetError() != GL_NO_ERROR) {
+ fprintf(stderr, "GL error!\n");
+ }
+
+ return true;
+ }
+
+private:
+ GLuint mBlitPgm;
+ GLint mPosAttribLoc;
+ GLint mUVAttribLoc;
+ GLint mUVToTexUniformLoc;
+ GLint mObjToNdcUniformLoc;
+ GLint mBlitSrcSamplerLoc;
+ GLint mModColorUniformLoc;
+};
+
+class ComposerBase : public Composer {
+public:
+ virtual ~ComposerBase() {}
+
+ virtual bool setUp(const LayerDesc& desc,
+ GLHelper* helper) {
+ mLayerDesc = desc;
+ return setUp(helper);
+ }
+
+ virtual void tearDown() {
+ }
+
+ virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) {
+ return true;
+ }
+
+protected:
+ virtual bool setUp(GLHelper* helper) {
+ return true;
+ }
+
+ LayerDesc mLayerDesc;
+};
+
+Composer* nocomp() {
+ class NoComp : public ComposerBase {
+ };
+ return new NoComp();
+}
+
+Composer* opaque() {
+ class OpaqueComp : public ComposerBase {
+ virtual bool setUp(GLHelper* helper) {
+ return mBlitter.setUp(helper);
+ }
+
+ virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) {
+ float texMatrix[16];
+ glc->getTransformMatrix(texMatrix);
+
+ int32_t x = mLayerDesc.x;
+ int32_t y = mLayerDesc.y;
+ int32_t w = mLayerDesc.width;
+ int32_t h = mLayerDesc.height;
+
+ return mBlitter.blit(texName, texMatrix, x, y, w, h);
+ }
+
+ Blitter mBlitter;
+ };
+ return new OpaqueComp();
+}
+
+Composer* opaqueShrink() {
+ class OpaqueComp : public ComposerBase {
+ virtual bool setUp(GLHelper* helper) {
+ mParity = false;
+ return mBlitter.setUp(helper);
+ }
+
+ virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) {
+ float texMatrix[16];
+ glc->getTransformMatrix(texMatrix);
+
+ int32_t x = mLayerDesc.x;
+ int32_t y = mLayerDesc.y;
+ int32_t w = mLayerDesc.width;
+ int32_t h = mLayerDesc.height;
+
+ mParity = !mParity;
+ if (mParity) {
+ x += w / 128;
+ y += h / 128;
+ w -= w / 64;
+ h -= h / 64;
+ }
+
+ return mBlitter.blit(texName, texMatrix, x, y, w, h);
+ }
+
+ Blitter mBlitter;
+ bool mParity;
+ };
+ return new OpaqueComp();
+}
+
+Composer* blend() {
+ class BlendComp : public ComposerBase {
+ virtual bool setUp(GLHelper* helper) {
+ return mBlitter.setUp(helper);
+ }
+
+ virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) {
+ bool result;
+
+ float texMatrix[16];
+ glc->getTransformMatrix(texMatrix);
+
+ float modColor[4] = { .75f, .75f, .75f, .75f };
+
+ int32_t x = mLayerDesc.x;
+ int32_t y = mLayerDesc.y;
+ int32_t w = mLayerDesc.width;
+ int32_t h = mLayerDesc.height;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ result = mBlitter.modBlit(texName, texMatrix, modColor,
+ x, y, w, h);
+ if (!result) {
+ return false;
+ }
+
+ glDisable(GL_BLEND);
+
+ return true;
+ }
+
+ Blitter mBlitter;
+ };
+ return new BlendComp();
+}
+
+Composer* blendShrink() {
+ class BlendShrinkComp : public ComposerBase {
+ virtual bool setUp(GLHelper* helper) {
+ mParity = false;
+ return mBlitter.setUp(helper);
+ }
+
+ virtual bool compose(GLuint texName, const sp<GLConsumer>& glc) {
+ bool result;
+
+ float texMatrix[16];
+ glc->getTransformMatrix(texMatrix);
+
+ float modColor[4] = { .75f, .75f, .75f, .75f };
+
+ int32_t x = mLayerDesc.x;
+ int32_t y = mLayerDesc.y;
+ int32_t w = mLayerDesc.width;
+ int32_t h = mLayerDesc.height;
+
+ mParity = !mParity;
+ if (mParity) {
+ x += w / 128;
+ y += h / 128;
+ w -= w / 64;
+ h -= h / 64;
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ result = mBlitter.modBlit(texName, texMatrix, modColor,
+ x, y, w, h);
+ if (!result) {
+ return false;
+ }
+
+ glDisable(GL_BLEND);
+
+ return true;
+ }
+
+ Blitter mBlitter;
+ bool mParity;
+ };
+ return new BlendShrinkComp();
+}
+
+} // namespace android