mipmap.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "context.h"
  20. #include "state.h"
  21. #include "texture.h"
  22. #include "TextureObjectManager.h"
  23. namespace android {
  24. // ----------------------------------------------------------------------------
  25. status_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex)
  26. {
  27. int level = 0;
  28. const GGLSurface* base = &tex->surface;
  29. const GGLFormat& pixelFormat(c->rasterizer.formats[base->format]);
  30. int w = base->width;
  31. int h = base->height;
  32. if ((w&h) == 1)
  33. return NO_ERROR;
  34. w = (w>>1) ? : 1;
  35. h = (h>>1) ? : 1;
  36. while(true) {
  37. ++level;
  38. const int bpr = w * pixelFormat.size;
  39. if (tex->reallocate(level, w, h, w,
  40. base->format, base->compressedFormat, bpr) != NO_ERROR) {
  41. return NO_MEMORY;
  42. }
  43. int stride = w;
  44. int bs = base->stride;
  45. GGLSurface& cur = tex->editMip(level);
  46. if (base->format == GGL_PIXEL_FORMAT_RGB_565)
  47. {
  48. uint16_t const * src = (uint16_t const *)base->data;
  49. uint16_t* dst = (uint16_t*)cur.data;
  50. const uint32_t mask = 0x07E0F81F;
  51. for (int y=0 ; y<h ; y++) {
  52. size_t offset = (y*2) * bs;
  53. for (int x=0 ; x<w ; x++) {
  54. uint32_t p00 = src[offset];
  55. uint32_t p10 = src[offset+1];
  56. uint32_t p01 = src[offset+bs];
  57. uint32_t p11 = src[offset+bs+1];
  58. p00 = (p00 | (p00 << 16)) & mask;
  59. p01 = (p01 | (p01 << 16)) & mask;
  60. p10 = (p10 | (p10 << 16)) & mask;
  61. p11 = (p11 | (p11 << 16)) & mask;
  62. uint32_t grb = ((p00 + p10 + p01 + p11) >> 2) & mask;
  63. uint32_t rgb = (grb & 0xFFFF) | (grb >> 16);
  64. dst[x + y*stride] = rgb;
  65. offset += 2;
  66. }
  67. }
  68. }
  69. else if (base->format == GGL_PIXEL_FORMAT_RGBA_5551)
  70. {
  71. uint16_t const * src = (uint16_t const *)base->data;
  72. uint16_t* dst = (uint16_t*)cur.data;
  73. for (int y=0 ; y<h ; y++) {
  74. size_t offset = (y*2) * bs;
  75. for (int x=0 ; x<w ; x++) {
  76. uint32_t p00 = src[offset];
  77. uint32_t p10 = src[offset+1];
  78. uint32_t p01 = src[offset+bs];
  79. uint32_t p11 = src[offset+bs+1];
  80. uint32_t r = ((p00>>11)+(p10>>11)+(p01>>11)+(p11>>11)+2)>>2;
  81. uint32_t g = (((p00>>6)+(p10>>6)+(p01>>6)+(p11>>6)+2)>>2)&0x3F;
  82. uint32_t b = ((p00&0x3E)+(p10&0x3E)+(p01&0x3E)+(p11&0x3E)+4)>>3;
  83. uint32_t a = ((p00&1)+(p10&1)+(p01&1)+(p11&1)+2)>>2;
  84. dst[x + y*stride] = (r<<11)|(g<<6)|(b<<1)|a;
  85. offset += 2;
  86. }
  87. }
  88. }
  89. else if (base->format == GGL_PIXEL_FORMAT_RGBA_8888)
  90. {
  91. uint32_t const * src = (uint32_t const *)base->data;
  92. uint32_t* dst = (uint32_t*)cur.data;
  93. for (int y=0 ; y<h ; y++) {
  94. size_t offset = (y*2) * bs;
  95. for (int x=0 ; x<w ; x++) {
  96. uint32_t p00 = src[offset];
  97. uint32_t p10 = src[offset+1];
  98. uint32_t p01 = src[offset+bs];
  99. uint32_t p11 = src[offset+bs+1];
  100. uint32_t rb00 = p00 & 0x00FF00FF;
  101. uint32_t rb01 = p01 & 0x00FF00FF;
  102. uint32_t rb10 = p10 & 0x00FF00FF;
  103. uint32_t rb11 = p11 & 0x00FF00FF;
  104. uint32_t ga00 = (p00 >> 8) & 0x00FF00FF;
  105. uint32_t ga01 = (p01 >> 8) & 0x00FF00FF;
  106. uint32_t ga10 = (p10 >> 8) & 0x00FF00FF;
  107. uint32_t ga11 = (p11 >> 8) & 0x00FF00FF;
  108. uint32_t rb = (rb00 + rb01 + rb10 + rb11)>>2;
  109. uint32_t ga = (ga00 + ga01 + ga10 + ga11)>>2;
  110. uint32_t rgba = (rb & 0x00FF00FF) | ((ga & 0x00FF00FF)<<8);
  111. dst[x + y*stride] = rgba;
  112. offset += 2;
  113. }
  114. }
  115. }
  116. else if ((base->format == GGL_PIXEL_FORMAT_RGB_888) ||
  117. (base->format == GGL_PIXEL_FORMAT_LA_88) ||
  118. (base->format == GGL_PIXEL_FORMAT_A_8) ||
  119. (base->format == GGL_PIXEL_FORMAT_L_8))
  120. {
  121. int skip;
  122. switch (base->format) {
  123. case GGL_PIXEL_FORMAT_RGB_888: skip = 3; break;
  124. case GGL_PIXEL_FORMAT_LA_88: skip = 2; break;
  125. default: skip = 1; break;
  126. }
  127. uint8_t const * src = (uint8_t const *)base->data;
  128. uint8_t* dst = (uint8_t*)cur.data;
  129. bs *= skip;
  130. stride *= skip;
  131. for (int y=0 ; y<h ; y++) {
  132. size_t offset = (y*2) * bs;
  133. for (int x=0 ; x<w ; x++) {
  134. for (int c=0 ; c<skip ; c++) {
  135. uint32_t p00 = src[c+offset];
  136. uint32_t p10 = src[c+offset+skip];
  137. uint32_t p01 = src[c+offset+bs];
  138. uint32_t p11 = src[c+offset+bs+skip];
  139. dst[x + y*stride + c] = (p00 + p10 + p01 + p11) >> 2;
  140. }
  141. offset += 2*skip;
  142. }
  143. }
  144. }
  145. else if (base->format == GGL_PIXEL_FORMAT_RGBA_4444)
  146. {
  147. uint16_t const * src = (uint16_t const *)base->data;
  148. uint16_t* dst = (uint16_t*)cur.data;
  149. for (int y=0 ; y<h ; y++) {
  150. size_t offset = (y*2) * bs;
  151. for (int x=0 ; x<w ; x++) {
  152. uint32_t p00 = src[offset];
  153. uint32_t p10 = src[offset+1];
  154. uint32_t p01 = src[offset+bs];
  155. uint32_t p11 = src[offset+bs+1];
  156. p00 = ((p00 << 12) & 0x0F0F0000) | (p00 & 0x0F0F);
  157. p10 = ((p10 << 12) & 0x0F0F0000) | (p10 & 0x0F0F);
  158. p01 = ((p01 << 12) & 0x0F0F0000) | (p01 & 0x0F0F);
  159. p11 = ((p11 << 12) & 0x0F0F0000) | (p11 & 0x0F0F);
  160. uint32_t rbga = (p00 + p10 + p01 + p11) >> 2;
  161. uint32_t rgba = (rbga & 0x0F0F) | ((rbga>>12) & 0xF0F0);
  162. dst[x + y*stride] = rgba;
  163. offset += 2;
  164. }
  165. }
  166. } else {
  167. ALOGE("Unsupported format (%d)", base->format);
  168. return BAD_TYPE;
  169. }
  170. // exit condition: we just processed the 1x1 LODs
  171. if ((w&h) == 1)
  172. break;
  173. base = &cur;
  174. w = (w>>1) ? : 1;
  175. h = (h>>1) ? : 1;
  176. }
  177. return NO_ERROR;
  178. }
  179. }; // namespace android