1211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/* 2211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * Copyright (C) 2012 The Android Open Source Project 3211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * 4211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * you may not use this file except in compliance with the License. 6211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * You may obtain a copy of the License at 7211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * 8211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * 10211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * Unless required by applicable law or agreed to in writing, software 11211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * See the License for the specific language governing permissions and 14211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy * limitations under the License. 15211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy */ 16211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 17211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy#include "Caches.h" 18211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy#include "Dither.h" 19211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 20211efea7376371ee755edd2ad03e83ef6eea464eRomain Guynamespace android { 21211efea7376371ee755edd2ad03e83ef6eea464eRomain Guynamespace uirenderer { 22211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 23211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 24211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy// Lifecycle 25211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 26211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 278aa195d7081b889f3a7b1f426cbd8556377aae5eRomain GuyDither::Dither(): mCaches(NULL), mInitialized(false), mDitherTexture(0) { 288aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy} 298aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 30211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::bindDitherTexture() { 31211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (!mInitialized) { 327f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool useFloatTexture = Extensions::getInstance().hasFloatTextures(); 33211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 34211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glGenTextures(1, &mDitherTexture); 358aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy mCaches->bindTexture(mDitherTexture); 36211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 37211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 38211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 39211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 40211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 41211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 42211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 43b48800428906ae455c2b63acacd44e390e1fee49Romain Guy if (useFloatTexture) { 44032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // We use a R16F texture, let's remap the alpha channel to the 45032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // red channel to avoid changing the shader sampling code on GL ES 3.0+ 46032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); 47032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy 48b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE); 49b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const GLfloat pattern[] = { 50b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0 * dither, 8 * dither, 2 * dither, 10 * dither, 51b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12 * dither, 4 * dither, 14 * dither, 6 * dither, 52b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3 * dither, 11 * dither, 1 * dither, 9 * dither, 53b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15 * dither, 7 * dither, 13 * dither, 5 * dither 54b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 55b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 56b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat)); 57b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 58b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_RED, GL_FLOAT, &pattern); 59b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } else { 60b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const uint8_t pattern[] = { 61b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0, 8, 2, 10, 62b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12, 4, 14, 6, 63b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3, 11, 1, 9, 64b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15, 7, 13, 5 65b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 66b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 67b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 68b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 69b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_ALPHA, GL_UNSIGNED_BYTE, &pattern); 70b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } 71211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 72211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy mInitialized = true; 73211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } else { 748aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy mCaches->bindTexture(mDitherTexture); 75211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 76211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 77211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 78211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::clear() { 79211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (mInitialized) { 80be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy mCaches->deleteTexture(mDitherTexture); 814abab937bf3f168763a7c029275bf1de151ec1aeRomain Guy mInitialized = false; 82211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 83211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 84211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 85211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 86211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy// Program management 87211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 88211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 89211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::setupProgram(Program* program, GLuint* textureUnit) { 908aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy if (!mCaches) mCaches = &Caches::getInstance(); 918aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 92211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy GLuint textureSlot = (*textureUnit)++; 938aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy mCaches->activeTexture(textureSlot); 94211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 95211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy bindDitherTexture(); 96211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 97211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glUniform1i(program->getUniform("ditherSampler"), textureSlot); 98211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 99211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 100211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace uirenderer 101211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace android 102