| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2010 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 <stdlib.h> | 
 | 18 | #include <stdint.h> | 
 | 19 | #include <sys/types.h> | 
 | 20 |  | 
 | 21 | #include <utils/Errors.h> | 
 | 22 | #include <utils/Log.h> | 
 | 23 |  | 
 | 24 | #include <ui/GraphicBuffer.h> | 
 | 25 |  | 
 | 26 | #include <GLES/gl.h> | 
 | 27 | #include <GLES/glext.h> | 
 | 28 |  | 
 | 29 | #include <hardware/hardware.h> | 
 | 30 |  | 
 | 31 | #include "clz.h" | 
 | 32 | #include "DisplayHardware/DisplayHardware.h" | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 33 | #include "GLExtensions.h" | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 34 | #include "TextureManager.h" | 
 | 35 |  | 
 | 36 | namespace android { | 
 | 37 |  | 
 | 38 | // --------------------------------------------------------------------------- | 
 | 39 |  | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 40 | TextureManager::TextureManager() | 
 | 41 |     : mGLExtensions(GLExtensions::getInstance()) | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 42 | { | 
 | 43 | } | 
 | 44 |  | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 45 | GLenum TextureManager::getTextureTarget(const Image* image) { | 
| Michael I. Gold | 7f198b6 | 2010-09-15 15:46:24 -0700 | [diff] [blame] | 46 | #if defined(GL_OES_EGL_image_external) | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 47 |     switch (image->target) { | 
 | 48 |         case Texture::TEXTURE_EXTERNAL: | 
 | 49 |             return GL_TEXTURE_EXTERNAL_OES; | 
 | 50 |     } | 
 | 51 | #endif | 
 | 52 |     return GL_TEXTURE_2D; | 
 | 53 | } | 
 | 54 |  | 
 | 55 | status_t TextureManager::initTexture(Texture* texture) | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 56 | { | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 57 |     if (texture->name != -1UL) | 
 | 58 |         return INVALID_OPERATION; | 
 | 59 |  | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 60 |     GLuint textureName = -1; | 
 | 61 |     glGenTextures(1, &textureName); | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 62 |     texture->name = textureName; | 
 | 63 |     texture->width = 0; | 
 | 64 |     texture->height = 0; | 
 | 65 |  | 
 | 66 |     const GLenum target = GL_TEXTURE_2D; | 
 | 67 |     glBindTexture(target, textureName); | 
 | 68 |     glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
 | 69 |     glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
 | 70 |     glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
 | 71 |     glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
 | 72 |  | 
 | 73 |     return NO_ERROR; | 
 | 74 | } | 
 | 75 |  | 
 | 76 | status_t TextureManager::initTexture(Image* pImage, int32_t format) | 
 | 77 | { | 
 | 78 |     if (pImage->name != -1UL) | 
 | 79 |         return INVALID_OPERATION; | 
 | 80 |  | 
 | 81 |     GLuint textureName = -1; | 
 | 82 |     glGenTextures(1, &textureName); | 
 | 83 |     pImage->name = textureName; | 
 | 84 |     pImage->width = 0; | 
 | 85 |     pImage->height = 0; | 
 | 86 |  | 
 | 87 |     GLenum target = GL_TEXTURE_2D; | 
| Michael I. Gold | 7f198b6 | 2010-09-15 15:46:24 -0700 | [diff] [blame] | 88 | #if defined(GL_OES_EGL_image_external) | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 89 |     if (GLExtensions::getInstance().haveTextureExternal()) { | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 90 |         if (format && isYuvFormat(format)) { | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 91 |             target = GL_TEXTURE_EXTERNAL_OES; | 
 | 92 |             pImage->target = Texture::TEXTURE_EXTERNAL; | 
 | 93 |         } | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 94 |     } | 
 | 95 | #endif | 
 | 96 |  | 
 | 97 |     glBindTexture(target, textureName); | 
 | 98 |     glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
 | 99 |     glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
 | 100 |     glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
 | 101 |     glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
 | 102 |  | 
 | 103 |     return NO_ERROR; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 104 | } | 
 | 105 |  | 
 | 106 | bool TextureManager::isSupportedYuvFormat(int format) | 
 | 107 | { | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 108 |     switch (format) { | 
 | 109 |     case HAL_PIXEL_FORMAT_YV12: | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 110 |         return true; | 
 | 111 |     } | 
 | 112 |     return false; | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 113 | } | 
 | 114 |  | 
 | 115 | bool TextureManager::isYuvFormat(int format) | 
 | 116 | { | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 117 |     switch (format) { | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 118 |     // supported YUV formats | 
 | 119 |     case HAL_PIXEL_FORMAT_YV12: | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 120 |     // Legacy/deprecated YUV formats | 
 | 121 |     case HAL_PIXEL_FORMAT_YCbCr_422_SP: | 
 | 122 |     case HAL_PIXEL_FORMAT_YCrCb_420_SP: | 
 | 123 |     case HAL_PIXEL_FORMAT_YCbCr_422_I: | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 124 |         return true; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 125 |     } | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 126 |  | 
 | 127 |     // Any OEM format needs to be considered | 
 | 128 |     if (format>=0x100 && format<=0x1FF) | 
 | 129 |         return true; | 
 | 130 |  | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 131 |     return false; | 
 | 132 | } | 
 | 133 |  | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 134 | status_t TextureManager::initEglImage(Image* pImage, | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 135 |         EGLDisplay dpy, const sp<GraphicBuffer>& buffer) | 
 | 136 | { | 
 | 137 |     status_t err = NO_ERROR; | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 138 |     if (!pImage->dirty) return err; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 139 |  | 
 | 140 |     // free the previous image | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 141 |     if (pImage->image != EGL_NO_IMAGE_KHR) { | 
 | 142 |         eglDestroyImageKHR(dpy, pImage->image); | 
 | 143 |         pImage->image = EGL_NO_IMAGE_KHR; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 144 |     } | 
 | 145 |  | 
 | 146 |     // construct an EGL_NATIVE_BUFFER_ANDROID | 
| Iliyan Malchev | 697526b | 2011-05-01 11:33:26 -0700 | [diff] [blame] | 147 |     ANativeWindowBuffer* clientBuf = buffer->getNativeBuffer(); | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 148 |  | 
 | 149 |     // create the new EGLImageKHR | 
 | 150 |     const EGLint attrs[] = { | 
 | 151 |             EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE, | 
 | 152 |             EGL_NONE,                   EGL_NONE | 
 | 153 |     }; | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 154 |     pImage->image = eglCreateImageKHR( | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 155 |             dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, | 
 | 156 |             (EGLClientBuffer)clientBuf, attrs); | 
 | 157 |  | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 158 |     if (pImage->image != EGL_NO_IMAGE_KHR) { | 
 | 159 |         if (pImage->name == -1UL) { | 
 | 160 |             initTexture(pImage, buffer->format); | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 161 |         } | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 162 |         const GLenum target = getTextureTarget(pImage); | 
 | 163 |         glBindTexture(target, pImage->name); | 
 | 164 |         glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image); | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 165 |         GLint error = glGetError(); | 
 | 166 |         if (error != GL_NO_ERROR) { | 
 | 167 |             LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x", | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 168 |                     pImage->image, error); | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 169 |             err = INVALID_OPERATION; | 
 | 170 |         } else { | 
 | 171 |             // Everything went okay! | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 172 |             pImage->dirty  = false; | 
 | 173 |             pImage->width  = clientBuf->width; | 
 | 174 |             pImage->height = clientBuf->height; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 175 |         } | 
 | 176 |     } else { | 
 | 177 |         LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError()); | 
 | 178 |         err = INVALID_OPERATION; | 
 | 179 |     } | 
 | 180 |     return err; | 
 | 181 | } | 
 | 182 |  | 
 | 183 | status_t TextureManager::loadTexture(Texture* texture, | 
 | 184 |         const Region& dirty, const GGLSurface& t) | 
 | 185 | { | 
 | 186 |     if (texture->name == -1UL) { | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 187 |         status_t err = initTexture(texture); | 
 | 188 |         LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err)); | 
| Ichitaro Kohara | dcab18c | 2011-02-18 13:15:04 +0100 | [diff] [blame] | 189 |         if (err != NO_ERROR) return err; | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 190 |     } | 
 | 191 |  | 
| Mathias Agopian | f1c468e | 2010-08-13 16:25:13 -0700 | [diff] [blame] | 192 |     if (texture->target != Texture::TEXTURE_2D) | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 193 |         return INVALID_OPERATION; | 
 | 194 |  | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 195 |     glBindTexture(GL_TEXTURE_2D, texture->name); | 
 | 196 |  | 
 | 197 |     /* | 
 | 198 |      * In OpenGL ES we can't specify a stride with glTexImage2D (however, | 
 | 199 |      * GL_UNPACK_ALIGNMENT is a limited form of stride). | 
 | 200 |      * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we | 
 | 201 |      * need to do something reasonable (here creating a bigger texture). | 
 | 202 |      * | 
 | 203 |      * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); | 
 | 204 |      * | 
 | 205 |      * This situation doesn't happen often, but some h/w have a limitation | 
 | 206 |      * for their framebuffer (eg: must be multiple of 8 pixels), and | 
 | 207 |      * we need to take that into account when using these buffers as | 
 | 208 |      * textures. | 
 | 209 |      * | 
 | 210 |      * This should never be a problem with POT textures | 
 | 211 |      */ | 
 | 212 |  | 
 | 213 |     int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); | 
 | 214 |     unpack = 1 << ((unpack > 3) ? 3 : unpack); | 
 | 215 |     glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); | 
 | 216 |  | 
 | 217 |     /* | 
 | 218 |      * round to POT if needed | 
 | 219 |      */ | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 220 |     if (!mGLExtensions.haveNpot()) { | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 221 |         texture->NPOTAdjust = true; | 
 | 222 |     } | 
 | 223 |  | 
 | 224 |     if (texture->NPOTAdjust) { | 
 | 225 |         // find the smallest power-of-two that will accommodate our surface | 
 | 226 |         texture->potWidth  = 1 << (31 - clz(t.width)); | 
 | 227 |         texture->potHeight = 1 << (31 - clz(t.height)); | 
 | 228 |         if (texture->potWidth  < t.width)  texture->potWidth  <<= 1; | 
 | 229 |         if (texture->potHeight < t.height) texture->potHeight <<= 1; | 
 | 230 |         texture->wScale = float(t.width)  / texture->potWidth; | 
 | 231 |         texture->hScale = float(t.height) / texture->potHeight; | 
 | 232 |     } else { | 
 | 233 |         texture->potWidth  = t.width; | 
 | 234 |         texture->potHeight = t.height; | 
 | 235 |     } | 
 | 236 |  | 
 | 237 |     Rect bounds(dirty.bounds()); | 
 | 238 |     GLvoid* data = 0; | 
 | 239 |     if (texture->width != t.width || texture->height != t.height) { | 
 | 240 |         texture->width  = t.width; | 
 | 241 |         texture->height = t.height; | 
 | 242 |  | 
 | 243 |         // texture size changed, we need to create a new one | 
 | 244 |         bounds.set(Rect(t.width, t.height)); | 
 | 245 |         if (t.width  == texture->potWidth && | 
 | 246 |             t.height == texture->potHeight) { | 
 | 247 |             // we can do it one pass | 
 | 248 |             data = t.data; | 
 | 249 |         } | 
 | 250 |  | 
 | 251 |         if (t.format == HAL_PIXEL_FORMAT_RGB_565) { | 
 | 252 |             glTexImage2D(GL_TEXTURE_2D, 0, | 
 | 253 |                     GL_RGB, texture->potWidth, texture->potHeight, 0, | 
 | 254 |                     GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); | 
 | 255 |         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { | 
 | 256 |             glTexImage2D(GL_TEXTURE_2D, 0, | 
 | 257 |                     GL_RGBA, texture->potWidth, texture->potHeight, 0, | 
 | 258 |                     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); | 
 | 259 |         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || | 
 | 260 |                    t.format == HAL_PIXEL_FORMAT_RGBX_8888) { | 
 | 261 |             glTexImage2D(GL_TEXTURE_2D, 0, | 
 | 262 |                     GL_RGBA, texture->potWidth, texture->potHeight, 0, | 
 | 263 |                     GL_RGBA, GL_UNSIGNED_BYTE, data); | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 264 |         } else if (isSupportedYuvFormat(t.format)) { | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 265 |             // just show the Y plane of YUV buffers | 
 | 266 |             glTexImage2D(GL_TEXTURE_2D, 0, | 
 | 267 |                     GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, | 
 | 268 |                     GL_LUMINANCE, GL_UNSIGNED_BYTE, data); | 
 | 269 |         } else { | 
 | 270 |             // oops, we don't handle this format! | 
 | 271 |             LOGE("texture=%d, using format %d, which is not " | 
 | 272 |                  "supported by the GL", texture->name, t.format); | 
 | 273 |         } | 
 | 274 |     } | 
 | 275 |     if (!data) { | 
 | 276 |         if (t.format == HAL_PIXEL_FORMAT_RGB_565) { | 
 | 277 |             glTexSubImage2D(GL_TEXTURE_2D, 0, | 
 | 278 |                     0, bounds.top, t.width, bounds.height(), | 
 | 279 |                     GL_RGB, GL_UNSIGNED_SHORT_5_6_5, | 
 | 280 |                     t.data + bounds.top*t.stride*2); | 
 | 281 |         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { | 
 | 282 |             glTexSubImage2D(GL_TEXTURE_2D, 0, | 
 | 283 |                     0, bounds.top, t.width, bounds.height(), | 
 | 284 |                     GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, | 
 | 285 |                     t.data + bounds.top*t.stride*2); | 
 | 286 |         } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || | 
 | 287 |                    t.format == HAL_PIXEL_FORMAT_RGBX_8888) { | 
 | 288 |             glTexSubImage2D(GL_TEXTURE_2D, 0, | 
 | 289 |                     0, bounds.top, t.width, bounds.height(), | 
 | 290 |                     GL_RGBA, GL_UNSIGNED_BYTE, | 
 | 291 |                     t.data + bounds.top*t.stride*4); | 
| Mathias Agopian | 1764c73 | 2010-07-01 21:17:56 -0700 | [diff] [blame] | 292 |         } else if (isSupportedYuvFormat(t.format)) { | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 293 |             // just show the Y plane of YUV buffers | 
 | 294 |             glTexSubImage2D(GL_TEXTURE_2D, 0, | 
 | 295 |                     0, bounds.top, t.width, bounds.height(), | 
 | 296 |                     GL_LUMINANCE, GL_UNSIGNED_BYTE, | 
 | 297 |                     t.data + bounds.top*t.stride); | 
 | 298 |         } | 
 | 299 |     } | 
 | 300 |     return NO_ERROR; | 
 | 301 | } | 
 | 302 |  | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 303 | void TextureManager::activateTexture(const Texture& texture, bool filter) | 
 | 304 | { | 
 | 305 |     const GLenum target = getTextureTarget(&texture); | 
| Mathias Agopian | 05650ae | 2010-06-28 19:54:17 -0700 | [diff] [blame] | 306 |     if (target == GL_TEXTURE_2D) { | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 307 |         glBindTexture(GL_TEXTURE_2D, texture.name); | 
 | 308 |         glEnable(GL_TEXTURE_2D); | 
| Michael I. Gold | 7f198b6 | 2010-09-15 15:46:24 -0700 | [diff] [blame] | 309 | #if defined(GL_OES_EGL_image_external) | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 310 |         if (GLExtensions::getInstance().haveTextureExternal()) { | 
 | 311 |             glDisable(GL_TEXTURE_EXTERNAL_OES); | 
 | 312 |         } | 
| Mathias Agopian | 05650ae | 2010-06-28 19:54:17 -0700 | [diff] [blame] | 313 |     } else { | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 314 |         glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.name); | 
 | 315 |         glEnable(GL_TEXTURE_EXTERNAL_OES); | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 316 |         glDisable(GL_TEXTURE_2D); | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 317 | #endif | 
| Mathias Agopian | 05650ae | 2010-06-28 19:54:17 -0700 | [diff] [blame] | 318 |     } | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 319 |  | 
 | 320 |     if (filter) { | 
 | 321 |         glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
 | 322 |         glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
 | 323 |     } else { | 
 | 324 |         glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 
 | 325 |         glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 
 | 326 |     } | 
 | 327 | } | 
 | 328 |  | 
 | 329 | void TextureManager::deactivateTextures() | 
 | 330 | { | 
 | 331 |     glDisable(GL_TEXTURE_2D); | 
| Michael I. Gold | 7f198b6 | 2010-09-15 15:46:24 -0700 | [diff] [blame] | 332 | #if defined(GL_OES_EGL_image_external) | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 333 |     if (GLExtensions::getInstance().haveTextureExternal()) { | 
 | 334 |         glDisable(GL_TEXTURE_EXTERNAL_OES); | 
 | 335 |     } | 
| Mathias Agopian | 0a91775 | 2010-06-14 21:20:00 -0700 | [diff] [blame] | 336 | #endif | 
 | 337 | } | 
 | 338 |  | 
| Mathias Agopian | d606de6 | 2010-05-10 20:06:11 -0700 | [diff] [blame] | 339 | // --------------------------------------------------------------------------- | 
 | 340 |  | 
 | 341 | }; // namespace android |