1 /* libs/opengles/mipmap.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 21 #include "context.h" 22 #include "state.h" 23 #include "texture.h" 24 #include "TextureObjectManager.h" 25 26 namespace android { 27 28 // ---------------------------------------------------------------------------- 29 30 status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex) 31 { 32 int level = 0; 33 const GGLSurface* base = &tex->surface; 34 const GGLFormat& pixelFormat(c->rasterizer.formats[base->format]); 35 36 int w = base->width; 37 int h = base->height; 38 if ((w&h) == 1) 39 return NO_ERROR; 40 41 w = (w>>1) ? : 1; 42 h = (h>>1) ? : 1; 43 44 while(true) { 45 ++level; 46 const int bpr = w * pixelFormat.size; 47 if (tex->reallocate(level, w, h, w, 48 base->format, base->compressedFormat, bpr) != NO_ERROR) { 49 return NO_MEMORY; 50 } 51 52 int stride = w; 53 int bs = base->stride; 54 GGLSurface& cur = tex->editMip(level); 55 56 if (base->format == GGL_PIXEL_FORMAT_RGB_565) 57 { 58 uint16_t const * src = (uint16_t const *)base->data; 59 uint16_t* dst = (uint16_t*)cur.data; 60 const uint32_t mask = 0x07E0F81F; 61 for (int y=0 ; y<h ; y++) { 62 size_t offset = (y*2) * bs; 63 for (int x=0 ; x<w ; x++) { 64 uint32_t p00 = src[offset]; 65 uint32_t p10 = src[offset+1]; 66 uint32_t p01 = src[offset+bs]; 67 uint32_t p11 = src[offset+bs+1]; 68 p00 = (p00 | (p00 << 16)) & mask; 69 p01 = (p01 | (p01 << 16)) & mask; 70 p10 = (p10 | (p10 << 16)) & mask; 71 p11 = (p11 | (p11 << 16)) & mask; 72 uint32_t grb = ((p00 + p10 + p01 + p11) >> 2) & mask; 73 uint32_t rgb = (grb & 0xFFFF) | (grb >> 16); 74 dst[x + y*stride] = rgb; 75 offset += 2; 76 } 77 } 78 } 79 else if (base->format == GGL_PIXEL_FORMAT_RGBA_5551) 80 { 81 uint16_t const * src = (uint16_t const *)base->data; 82 uint16_t* dst = (uint16_t*)cur.data; 83 for (int y=0 ; y<h ; y++) { 84 size_t offset = (y*2) * bs; 85 for (int x=0 ; x<w ; x++) { 86 uint32_t p00 = src[offset]; 87 uint32_t p10 = src[offset+1]; 88 uint32_t p01 = src[offset+bs]; 89 uint32_t p11 = src[offset+bs+1]; 90 uint32_t r = ((p00>>11)+(p10>>11)+(p01>>11)+(p11>>11)+2)>>2; 91 uint32_t g = (((p00>>6)+(p10>>6)+(p01>>6)+(p11>>6)+2)>>2)&0x3F; 92 uint32_t b = ((p00&0x3E)+(p10&0x3E)+(p01&0x3E)+(p11&0x3E)+4)>>3; 93 uint32_t a = ((p00&1)+(p10&1)+(p01&1)+(p11&1)+2)>>2; 94 dst[x + y*stride] = (r<<11)|(g<<6)|(b<<1)|a; 95 offset += 2; 96 } 97 } 98 } 99 else if (base->format == GGL_PIXEL_FORMAT_RGBA_8888) 100 { 101 uint32_t const * src = (uint32_t const *)base->data; 102 uint32_t* dst = (uint32_t*)cur.data; 103 for (int y=0 ; y<h ; y++) { 104 size_t offset = (y*2) * bs; 105 for (int x=0 ; x<w ; x++) { 106 uint32_t p00 = src[offset]; 107 uint32_t p10 = src[offset+1]; 108 uint32_t p01 = src[offset+bs]; 109 uint32_t p11 = src[offset+bs+1]; 110 uint32_t rb00 = p00 & 0x00FF00FF; 111 uint32_t rb01 = p01 & 0x00FF00FF; 112 uint32_t rb10 = p10 & 0x00FF00FF; 113 uint32_t rb11 = p11 & 0x00FF00FF; 114 uint32_t ga00 = (p00 >> 8) & 0x00FF00FF; 115 uint32_t ga01 = (p01 >> 8) & 0x00FF00FF; 116 uint32_t ga10 = (p10 >> 8) & 0x00FF00FF; 117 uint32_t ga11 = (p11 >> 8) & 0x00FF00FF; 118 uint32_t rb = (rb00 + rb01 + rb10 + rb11)>>2; 119 uint32_t ga = (ga00 + ga01 + ga10 + ga11)>>2; 120 uint32_t rgba = (rb & 0x00FF00FF) | ((ga & 0x00FF00FF)<<8); 121 dst[x + y*stride] = rgba; 122 offset += 2; 123 } 124 } 125 } 126 else if ((base->format == GGL_PIXEL_FORMAT_RGB_888) || 127 (base->format == GGL_PIXEL_FORMAT_LA_88) || 128 (base->format == GGL_PIXEL_FORMAT_A_8) || 129 (base->format == GGL_PIXEL_FORMAT_L_8)) 130 { 131 int skip; 132 switch (base->format) { 133 case GGL_PIXEL_FORMAT_RGB_888: skip = 3; break; 134 case GGL_PIXEL_FORMAT_LA_88: skip = 2; break; 135 default: skip = 1; break; 136 } 137 uint8_t const * src = (uint8_t const *)base->data; 138 uint8_t* dst = (uint8_t*)cur.data; 139 bs *= skip; 140 stride *= skip; 141 for (int y=0 ; y<h ; y++) { 142 size_t offset = (y*2) * bs; 143 for (int x=0 ; x<w ; x++) { 144 for (int c=0 ; c<skip ; c++) { 145 uint32_t p00 = src[c+offset]; 146 uint32_t p10 = src[c+offset+skip]; 147 uint32_t p01 = src[c+offset+bs]; 148 uint32_t p11 = src[c+offset+bs+skip]; 149 dst[x + y*stride + c] = (p00 + p10 + p01 + p11) >> 2; 150 } 151 offset += 2*skip; 152 } 153 } 154 } 155 else if (base->format == GGL_PIXEL_FORMAT_RGBA_4444) 156 { 157 uint16_t const * src = (uint16_t const *)base->data; 158 uint16_t* dst = (uint16_t*)cur.data; 159 for (int y=0 ; y<h ; y++) { 160 size_t offset = (y*2) * bs; 161 for (int x=0 ; x<w ; x++) { 162 uint32_t p00 = src[offset]; 163 uint32_t p10 = src[offset+1]; 164 uint32_t p01 = src[offset+bs]; 165 uint32_t p11 = src[offset+bs+1]; 166 p00 = ((p00 << 12) & 0x0F0F0000) | (p00 & 0x0F0F); 167 p10 = ((p10 << 12) & 0x0F0F0000) | (p10 & 0x0F0F); 168 p01 = ((p01 << 12) & 0x0F0F0000) | (p01 & 0x0F0F); 169 p11 = ((p11 << 12) & 0x0F0F0000) | (p11 & 0x0F0F); 170 uint32_t rbga = (p00 + p10 + p01 + p11) >> 2; 171 uint32_t rgba = (rbga & 0x0F0F) | ((rbga>>12) & 0xF0F0); 172 dst[x + y*stride] = rgba; 173 offset += 2; 174 } 175 } 176 } else { 177 ALOGE("Unsupported format (%d)", base->format); 178 return BAD_TYPE; 179 } 180 181 // exit condition: we just processed the 1x1 LODs 182 if ((w&h) == 1) 183 break; 184 185 base = &cur; 186 w = (w>>1) ? : 1; 187 h = (h>>1) ? : 1; 188 } 189 return NO_ERROR; 190 } 191 192 }; // namespace android 193