Dither.cpp revision 6c15ffa196fc9b7724c189d833c3435d8db12266
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 2744eb2c00861098dd3e2950d923646814b4cc57c2Chris CraikDither::Dither(Caches& caches) 2844eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik : mCaches(caches) 2944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik , mInitialized(false) 3044eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik , mDitherTexture(0) { 318aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy} 328aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 33211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::bindDitherTexture() { 34211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (!mInitialized) { 357f4307668b10467ee39d41c7ea29cf1ff238a835Romain Guy bool useFloatTexture = Extensions::getInstance().hasFloatTextures(); 36211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 37211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glGenTextures(1, &mDitherTexture); 3844eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.textureState().bindTexture(mDitherTexture); 39211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 40211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 41211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 42211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 43211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 44211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 45211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 46b48800428906ae455c2b63acacd44e390e1fee49Romain Guy if (useFloatTexture) { 47032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // We use a R16F texture, let's remap the alpha channel to the 48032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy // red channel to avoid changing the shader sampling code on GL ES 3.0+ 49032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); 50032d47af737d803e841ab79f38ac9068a46c9aebRomain Guy 51b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE); 52b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const GLfloat pattern[] = { 53b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0 * dither, 8 * dither, 2 * dither, 10 * dither, 54b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12 * dither, 4 * dither, 14 * dither, 6 * dither, 55b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3 * dither, 11 * dither, 1 * dither, 9 * dither, 56b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15 * dither, 7 * dither, 13 * dither, 5 * dither 57b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 58b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 59b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat)); 60b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 61b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_RED, GL_FLOAT, &pattern); 62b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } else { 63b48800428906ae455c2b63acacd44e390e1fee49Romain Guy const uint8_t pattern[] = { 64b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 0, 8, 2, 10, 65b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 12, 4, 14, 6, 66b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 3, 11, 1, 9, 67b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 15, 7, 13, 5 68b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 69b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 70b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 71b48800428906ae455c2b63acacd44e390e1fee49Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 72b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GL_ALPHA, GL_UNSIGNED_BYTE, &pattern); 73b48800428906ae455c2b63acacd44e390e1fee49Romain Guy } 74211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 75211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy mInitialized = true; 76211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } else { 7744eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.textureState().bindTexture(mDitherTexture); 78211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 79211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 80211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 81211efea7376371ee755edd2ad03e83ef6eea464eRomain Guyvoid Dither::clear() { 82211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy if (mInitialized) { 8344eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.textureState().deleteTexture(mDitherTexture); 844abab937bf3f168763a7c029275bf1de151ec1aeRomain Guy mInitialized = false; 85211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy } 86211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 87211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 88211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 89211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy// Program management 90211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy/////////////////////////////////////////////////////////////////////////////// 91211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 926c15ffa196fc9b7724c189d833c3435d8db12266Chris Craikvoid Dither::setupProgram(Program& program, GLuint* textureUnit) { 93211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy GLuint textureSlot = (*textureUnit)++; 9444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches.textureState().activateTexture(textureSlot); 95211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 96211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy bindDitherTexture(); 97211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 986c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glUniform1i(program.getUniform("ditherSampler"), textureSlot); 99211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy} 100211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy 101211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace uirenderer 102211efea7376371ee755edd2ad03e83ef6eea464eRomain Guy}; // namespace android 103