Dither.cpp revision 4abab937bf3f168763a7c029275bf1de151ec1ae
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 27211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::bindDitherTexture() { 28211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (!mInitialized) { 29b48800428906ae455c2b63acacd44e390e1fee49Romain Guy bool useFloatTexture = Extensions::getInstance().getMajorGlVersion() >= 3; 30211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 31211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glGenTextures(1, &mDitherTexture); 32211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glBindTexture(GL_TEXTURE_2D, mDitherTexture); 33211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 34211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 35211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 36211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 37211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 38211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 39211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 40b48800428906ae455c2b63acacd44e390e1fee49Romain Guy if (useFloatTexture) { 41032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // We use a R16F texture, let's remap the alpha channel to the 42032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // red channel to avoid changing the shader sampling code on GL ES 3.0+ 43032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); 44032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy 45b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE); 46b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const GLfloat pattern[] = { 47b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0 * dither, 8 * dither, 2 * dither, 10 * dither, 48b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12 * dither, 4 * dither, 14 * dither, 6 * dither, 49b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3 * dither, 11 * dither, 1 * dither, 9 * dither, 50b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15 * dither, 7 * dither, 13 * dither, 5 * dither 51b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 52b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 53b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat)); 54b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 55b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_RED, GL_FLOAT, &pattern); 56b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } else { 57b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const uint8_t pattern[] = { 58b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0, 8, 2, 10, 59b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12, 4, 14, 6, 60b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3, 11, 1, 9, 61b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15, 7, 13, 5 62b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 63b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 64b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 65b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 66b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_ALPHA, GL_UNSIGNED_BYTE, &pattern); 67b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } 68211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 69211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy mInitialized = true; 70211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } else { 71211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glBindTexture(GL_TEXTURE_2D, mDitherTexture); 72211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 73211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 74211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 75211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::clear() { 76211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (mInitialized) { 77211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glDeleteTextures(1, &mDitherTexture); 784abab937bf3f168763a7c029275bf1de151ec1aeRomain Guy mInitialized = false; 79211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 80211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 81211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 82211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 83211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy// Program management 84211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 85211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 86211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::setupProgram(Program* program, GLuint* textureUnit) { 87211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy GLuint textureSlot = (*textureUnit)++; 88211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy Caches::getInstance().activeTexture(textureSlot); 89211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 90211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy bindDitherTexture(); 91211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 92211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glUniform1i(program->getUniform("ditherSampler"), textureSlot); 93211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 94211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 95211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace uirenderer 96211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace android 97