19c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis/* 29c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Copyright (C) 2012 The Android Open Source Project 39c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * 49c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 59c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * you may not use this file except in compliance with the License. 69c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * You may obtain a copy of the License at 79c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * 89c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 99c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * 109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Unless required by applicable law or agreed to in writing, software 119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * See the License for the specific language governing permissions and 149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * limitations under the License. 159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis */ 169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis#include <ui/DisplayInfo.h> 189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis#include <gui/SurfaceComposerClient.h> 199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis#include "GLHelper.h" 219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis namespace android { 239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 249c183f2493222000fa512d927cfde3f4c748eda0Jamie GennisGLHelper::GLHelper() : 259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mGraphicBufferAlloc(new GraphicBufferAlloc()), 269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDisplay(EGL_NO_DISPLAY), 279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mContext(EGL_NO_CONTEXT), 289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDummySurface(EGL_NO_SURFACE), 299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mConfig(0), 309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mShaderPrograms(NULL), 319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDitherTexture(0) { 329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 349c183f2493222000fa512d927cfde3f4c748eda0Jamie GennisGLHelper::~GLHelper() { 359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::setUp(const ShaderDesc* shaderDescs, size_t numShaders) { 389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis bool result; 399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mDisplay == EGL_NO_DISPLAY) { 429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglGetDisplay error: %#x\n", eglGetError()); 439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint majorVersion; 479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint minorVersion; 489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = eglInitialize(mDisplay, &majorVersion, &minorVersion); 499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (result != EGL_TRUE) { 509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglInitialize error: %#x\n", eglGetError()); 519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint numConfigs = 0; 559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint configAttribs[] = { 569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_RED_SIZE, 8, 599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_GREEN_SIZE, 8, 609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_BLUE_SIZE, 8, 619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_ALPHA_SIZE, 8, 629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_NONE 639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis }; 649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = eglChooseConfig(mDisplay, configAttribs, &mConfig, 1, 659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis &numConfigs); 669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (result != EGL_TRUE) { 679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglChooseConfig error: %#x\n", eglGetError()); 689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint contextAttribs[] = { 729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_CONTEXT_CLIENT_VERSION, 2, 739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_NONE 749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis }; 759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, 769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis contextAttribs); 779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mContext == EGL_NO_CONTEXT) { 789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglCreateContext error: %#x\n", eglGetError()); 799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis bool resultb = createNamedSurfaceTexture(0, 1, 1, &mDummyGLConsumer, 839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis &mDummySurface); 849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!resultb) { 859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis resultb = makeCurrent(mDummySurface); 899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!resultb) { 909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis resultb = setUpShaders(shaderDescs, numShaders); 949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!resultb) { 959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 989c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 999c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1009c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1019c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisvoid GLHelper::tearDown() { 1029c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mShaderPrograms != NULL) { 1039c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis delete[] mShaderPrograms; 1049c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mShaderPrograms = NULL; 1059c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1069c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1079c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mSurfaceComposerClient != NULL) { 1089c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mSurfaceComposerClient->dispose(); 1099c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mSurfaceComposerClient.clear(); 1109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mDisplay != EGL_NO_DISPLAY) { 1139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 1149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_NO_CONTEXT); 1159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mContext != EGL_NO_CONTEXT) { 1189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglDestroyContext(mDisplay, mContext); 1199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mDummySurface != EGL_NO_SURFACE) { 1229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglDestroySurface(mDisplay, mDummySurface); 1239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDisplay = EGL_NO_DISPLAY; 1269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mContext = EGL_NO_CONTEXT; 1279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDummySurface = EGL_NO_SURFACE; 1289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mDummyGLConsumer.clear(); 1299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mConfig = 0; 1309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::makeCurrent(EGLSurface surface) { 1339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint result; 1349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = eglMakeCurrent(mDisplay, surface, surface, mContext); 1369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (result != EGL_TRUE) { 1379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglMakeCurrent error: %#x\n", eglGetError()); 1389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 1399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint w, h; 1429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglQuerySurface(mDisplay, surface, EGL_WIDTH, &w); 1439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglQuerySurface(mDisplay, surface, EGL_HEIGHT, &h); 1449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glViewport(0, 0, w, h); 1459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 1479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::createSurfaceTexture(uint32_t w, uint32_t h, 1509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<GLConsumer>* glConsumer, EGLSurface* surface, 1519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint* name) { 1529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!makeCurrent(mDummySurface)) { 1539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 1549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *name = 0; 1579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGenTextures(1, name); 1589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (*name == 0) { 1599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "glGenTextures error: %#x\n", glGetError()); 1609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 1619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return createNamedSurfaceTexture(*name, w, h, glConsumer, surface); 1649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisvoid GLHelper::destroySurface(EGLSurface* surface) { 1679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (eglGetCurrentSurface(EGL_READ) == *surface || 1689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglGetCurrentSurface(EGL_DRAW) == *surface) { 1699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 1709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGL_NO_CONTEXT); 1719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis eglDestroySurface(mDisplay, *surface); 1739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *surface = EGL_NO_SURFACE; 1749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::swapBuffers(EGLSurface surface) { 1779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLint result; 1789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = eglSwapBuffers(mDisplay, surface); 1799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (result != EGL_TRUE) { 1809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglSwapBuffers error: %#x\n", eglGetError()); 1819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 1829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 1849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) { 1879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis for (size_t i = 0; i < mNumShaders; i++) { 1889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (strcmp(mShaderDescs[i].name, name) == 0) { 1899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *outPgm = mShaderPrograms[i]; 1909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 1919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 1939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "unknown shader name: \"%s\"\n", name); 1959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 1979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 1989c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 1999c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, 2009c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<GLConsumer>* glConsumer, EGLSurface* surface) { 2019c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<BufferQueue> bq = new BufferQueue(true, mGraphicBufferAlloc); 2029c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<GLConsumer> glc = new GLConsumer(name, true, 2039c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GL_TEXTURE_EXTERNAL_OES, false, bq); 2049c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glc->setDefaultBufferSize(w, h); 2059c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glc->setDefaultMaxBufferCount(3); 2069c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glc->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); 2079c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 208e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian sp<ANativeWindow> anw = new Surface(bq); 2099c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL); 2109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (s == EGL_NO_SURFACE) { 2119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError()); 2129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *glConsumer = glc; 2169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *surface = s; 2179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 2189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 2199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) { 2219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<IBinder> dpy = mSurfaceComposerClient->getBuiltInDisplay(0); 2229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (dpy == NULL) { 2239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n"); 2249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis DisplayInfo info; 2289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis status_t err = mSurfaceComposerClient->getDisplayInfo(dpy, &info); 2299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (err != NO_ERROR) { 2309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposer::getDisplayInfo failed: %#x\n", err); 2319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis float scaleX = float(info.w) / float(w); 2359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis float scaleY = float(info.h) / float(h); 2369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *scale = scaleX < scaleY ? scaleX : scaleY; 2379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 2399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 2409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::createWindowSurface(uint32_t w, uint32_t h, 2429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<SurfaceControl>* surfaceControl, EGLSurface* surface) { 2439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis bool result; 2449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis status_t err; 2459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mSurfaceComposerClient == NULL) { 2479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mSurfaceComposerClient = new SurfaceComposerClient; 2489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis err = mSurfaceComposerClient->initCheck(); 2509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (err != NO_ERROR) { 2519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err); 2529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<SurfaceControl> sc = mSurfaceComposerClient->createSurface( 2569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis String8("Benchmark"), w, h, PIXEL_FORMAT_RGBA_8888, 0); 2579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (sc == NULL || !sc->isValid()) { 2589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "Failed to create SurfaceControl.\n"); 2599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis float scale; 2639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = computeWindowScale(w, h, &scale); 2649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!result) { 2659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis SurfaceComposerClient::openGlobalTransaction(); 2699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis err = sc->setLayer(0x7FFFFFFF); 2709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (err != NO_ERROR) { 2719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposer::setLayer error: %#x\n", err); 2729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis err = sc->setMatrix(scale, 0.0f, 0.0f, scale); 2759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (err != NO_ERROR) { 2769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposer::setMatrix error: %#x\n", err); 2779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis err = sc->show(); 2819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (err != NO_ERROR) { 2829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "SurfaceComposer::show error: %#x\n", err); 2839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis SurfaceComposerClient::closeGlobalTransaction(); 2869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis sp<ANativeWindow> anw = sc->getSurface(); 2889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis EGLSurface s = eglCreateWindowSurface(mDisplay, mConfig, anw.get(), NULL); 2899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (s == EGL_NO_SURFACE) { 2909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "eglCreateWindowSurface error: %#x\n", eglGetError()); 2919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 2929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 2939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *surfaceControl = sc; 2959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *surface = s; 2969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 2979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 2989c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 2999c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic bool compileShader(GLenum shaderType, const char* src, 3009c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint* outShader) { 3019c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint shader = glCreateShader(shaderType); 3029c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (shader == 0) { 3039c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "glCreateShader error: %#x\n", glGetError()); 3049c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 3059c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3069c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3079c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glShaderSource(shader, 1, &src, NULL); 3089c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glCompileShader(shader); 3099c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLint compiled = 0; 3119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 3129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!compiled) { 3139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLint infoLen = 0; 3149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 3159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (infoLen) { 3169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis char* buf = new char[infoLen]; 3179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (buf) { 3189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetShaderInfoLog(shader, infoLen, NULL, buf); 3199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "Shader compile log:\n%s\n", buf); 3209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis delete[] buf; 3219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glDeleteShader(shader); 3249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 3259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *outShader = shader; 3279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 3289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 3299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic void printShaderSource(const char* const* src) { 3319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) { 3329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "%3d: %s\n", i+1, src[i]); 3339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 3359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic const char* makeShaderString(const char* const* src) { 3379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis size_t len = 0; 3389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) { 3399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis // The +1 is for the '\n' that will be added. 3409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis len += strlen(src[i]) + 1; 3419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis char* result = new char[len+1]; 3449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis char* end = result; 3459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis for (size_t i = 0; i < MAX_SHADER_LINES && src[i] != NULL; i++) { 3469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis strcpy(end, src[i]); 3479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis end += strlen(src[i]); 3489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *end = '\n'; 3499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis end++; 3509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *end = '\0'; 3529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return result; 3549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 3559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic bool compileShaderLines(GLenum shaderType, const char* const* lines, 3579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint* outShader) { 3589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis const char* src = makeShaderString(lines); 3599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis bool result = compileShader(shaderType, src, outShader); 3609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!result) { 3619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "Shader source:\n"); 3629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis printShaderSource(lines); 3639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 3649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis delete[] src; 3669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 3689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 3699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic bool linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) { 3719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint program = glCreateProgram(); 3729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (program == 0) { 3739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "glCreateProgram error: %#x\n", glGetError()); 3749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 3759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glAttachShader(program, vs); 3789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glAttachShader(program, fs); 3799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glLinkProgram(program); 3809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLint linkStatus = GL_FALSE; 3819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 3829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (linkStatus != GL_TRUE) { 3839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLint bufLength = 0; 3849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 3859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (bufLength) { 3869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis char* buf = new char[bufLength]; 3879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (buf) { 3889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGetProgramInfoLog(program, bufLength, NULL, buf); 3899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis fprintf(stderr, "Program link log:\n%s\n", buf); 3909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis delete[] buf; 3919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glDeleteProgram(program); 3949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis program = 0; 3959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 3969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *outPgm = program; 3989c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return program != 0; 3999c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 4009c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4019c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::setUpShaders(const ShaderDesc* shaderDescs, size_t numShaders) { 4029c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mShaderPrograms = new GLuint[numShaders]; 4039c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis bool result = true; 4049c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4059c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis for (size_t i = 0; i < numShaders && result; i++) { 4069c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis GLuint vs, fs; 4079c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4089c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = compileShaderLines(GL_VERTEX_SHADER, 4099c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis shaderDescs[i].vertexShader, &vs); 4109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!result) { 4119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 4129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 4139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = compileShaderLines(GL_FRAGMENT_SHADER, 4159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis shaderDescs[i].fragmentShader, &fs); 4169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (!result) { 4179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glDeleteShader(vs); 4189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return false; 4199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 4209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis result = linkShaderProgram(vs, fs, &mShaderPrograms[i]); 4229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glDeleteShader(vs); 4239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glDeleteShader(fs); 4249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 4259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mNumShaders = numShaders; 4279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis mShaderDescs = shaderDescs; 4289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return result; 4309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 4319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisbool GLHelper::getDitherTexture(GLuint* outTexName) { 4339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis if (mDitherTexture == 0) { 4349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis const uint8_t pattern[] = { 4359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 0, 8, 2, 10, 4369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 12, 4, 14, 6, 4379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 3, 11, 1, 9, 4389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 15, 7, 13, 5 4399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis }; 4409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glGenTextures(1, &mDitherTexture); 4429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glBindTexture(GL_TEXTURE_2D, mDitherTexture); 4439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 4489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 4499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, 4519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis DITHER_KERNEL_SIZE, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &pattern); 4529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis } 4539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *outTexName = mDitherTexture; 4559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis return true; 4579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 4589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis 4599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} 460