Dither.cpp revision 44eb2c00861098dd3e2950d923646814b4cc57c2
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "Caches.h" 18#include "Dither.h" 19 20namespace android { 21namespace uirenderer { 22 23/////////////////////////////////////////////////////////////////////////////// 24// Lifecycle 25/////////////////////////////////////////////////////////////////////////////// 26 27Dither::Dither(Caches& caches) 28 : mCaches(caches) 29 , mInitialized(false) 30 , mDitherTexture(0) { 31} 32 33void Dither::bindDitherTexture() { 34 if (!mInitialized) { 35 bool useFloatTexture = Extensions::getInstance().hasFloatTextures(); 36 37 glGenTextures(1, &mDitherTexture); 38 mCaches.textureState().bindTexture(mDitherTexture); 39 40 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 41 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 42 43 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 44 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 45 46 if (useFloatTexture) { 47 // We use a R16F texture, let's remap the alpha channel to the 48 // red channel to avoid changing the shader sampling code on GL ES 3.0+ 49 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); 50 51 float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE); 52 const GLfloat pattern[] = { 53 0 * dither, 8 * dither, 2 * dither, 10 * dither, 54 12 * dither, 4 * dither, 14 * dither, 6 * dither, 55 3 * dither, 11 * dither, 1 * dither, 9 * dither, 56 15 * dither, 7 * dither, 13 * dither, 5 * dither 57 }; 58 59 glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat)); 60 glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 61 GL_RED, GL_FLOAT, &pattern); 62 } else { 63 const uint8_t pattern[] = { 64 0, 8, 2, 10, 65 12, 4, 14, 6, 66 3, 11, 1, 9, 67 15, 7, 13, 5 68 }; 69 70 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 71 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0, 72 GL_ALPHA, GL_UNSIGNED_BYTE, &pattern); 73 } 74 75 mInitialized = true; 76 } else { 77 mCaches.textureState().bindTexture(mDitherTexture); 78 } 79} 80 81void Dither::clear() { 82 if (mInitialized) { 83 mCaches.textureState().deleteTexture(mDitherTexture); 84 mInitialized = false; 85 } 86} 87 88/////////////////////////////////////////////////////////////////////////////// 89// Program management 90/////////////////////////////////////////////////////////////////////////////// 91 92void Dither::setupProgram(Program* program, GLuint* textureUnit) { 93 GLuint textureSlot = (*textureUnit)++; 94 mCaches.textureState().activateTexture(textureSlot); 95 96 bindDitherTexture(); 97 98 glUniform1i(program->getUniform("ditherSampler"), textureSlot); 99} 100 101}; // namespace uirenderer 102}; // namespace android 103