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