clear.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* libs/pixelflinger/clear.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 <cutils/memory.h>
  18. #include "clear.h"
  19. #include "buffer.h"
  20. namespace android {
  21. // ----------------------------------------------------------------------------
  22. static void ggl_clear(void* c, GGLbitfield mask);
  23. static void ggl_clearColorx(void* c,
  24. GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a);
  25. static void ggl_clearDepthx(void* c, GGLclampx depth);
  26. static void ggl_clearStencil(void* c, GGLint s);
  27. // ----------------------------------------------------------------------------
  28. void ggl_init_clear(context_t* c)
  29. {
  30. GGLContext& procs = *(GGLContext*)c;
  31. GGL_INIT_PROC(procs, clear);
  32. GGL_INIT_PROC(procs, clearColorx);
  33. GGL_INIT_PROC(procs, clearDepthx);
  34. GGL_INIT_PROC(procs, clearStencil);
  35. c->state.clear.dirty = GGL_STENCIL_BUFFER_BIT |
  36. GGL_COLOR_BUFFER_BIT |
  37. GGL_DEPTH_BUFFER_BIT;
  38. c->state.clear.depth = FIXED_ONE;
  39. }
  40. // ----------------------------------------------------------------------------
  41. static void memset2d(context_t* c, const surface_t& s, uint32_t packed,
  42. uint32_t l, uint32_t t, uint32_t w, uint32_t h)
  43. {
  44. const uint32_t size = c->formats[s.format].size;
  45. const int32_t stride = s.stride * size;
  46. uint8_t* dst = (uint8_t*)s.data + (l + t*s.stride)*size;
  47. w *= size;
  48. if (ggl_likely(int32_t(w) == stride)) {
  49. // clear the whole thing in one call
  50. w *= h;
  51. h = 1;
  52. }
  53. switch (size) {
  54. case 1:
  55. do {
  56. memset(dst, packed, w);
  57. dst += stride;
  58. } while(--h);
  59. break;
  60. case 2:
  61. do {
  62. android_memset16((uint16_t*)dst, packed, w);
  63. dst += stride;
  64. } while(--h);
  65. break;
  66. case 3: // XXX: 24-bit clear.
  67. break;
  68. case 4:
  69. do {
  70. android_memset32((uint32_t*)dst, packed, w);
  71. dst += stride;
  72. } while(--h);
  73. break;
  74. }
  75. }
  76. static inline GGLfixed fixedToZ(GGLfixed z) {
  77. return GGLfixed(((int64_t(z) << 16) - z) >> 16);
  78. }
  79. static void ggl_clear(void* con, GGLbitfield mask)
  80. {
  81. GGL_CONTEXT(c, con);
  82. // XXX: rgba-dithering, rgba-masking
  83. // XXX: handle all formats of Z and S
  84. const uint32_t l = c->state.scissor.left;
  85. const uint32_t t = c->state.scissor.top;
  86. uint32_t w = c->state.scissor.right - l;
  87. uint32_t h = c->state.scissor.bottom - t;
  88. if (!w || !h)
  89. return;
  90. // unexsiting buffers have no effect...
  91. if (c->state.buffers.color.format == 0)
  92. mask &= ~GGL_COLOR_BUFFER_BIT;
  93. if (c->state.buffers.depth.format == 0)
  94. mask &= ~GGL_DEPTH_BUFFER_BIT;
  95. if (c->state.buffers.stencil.format == 0)
  96. mask &= ~GGL_STENCIL_BUFFER_BIT;
  97. if (mask & GGL_COLOR_BUFFER_BIT) {
  98. if (c->state.clear.dirty & GGL_COLOR_BUFFER_BIT) {
  99. c->state.clear.dirty &= ~GGL_COLOR_BUFFER_BIT;
  100. uint32_t colorPacked = ggl_pack_color(c,
  101. c->state.buffers.color.format,
  102. gglFixedToIteratedColor(c->state.clear.r),
  103. gglFixedToIteratedColor(c->state.clear.g),
  104. gglFixedToIteratedColor(c->state.clear.b),
  105. gglFixedToIteratedColor(c->state.clear.a));
  106. c->state.clear.colorPacked = GGL_HOST_TO_RGBA(colorPacked);
  107. }
  108. const uint32_t packed = c->state.clear.colorPacked;
  109. memset2d(c, c->state.buffers.color, packed, l, t, w, h);
  110. }
  111. if (mask & GGL_DEPTH_BUFFER_BIT) {
  112. if (c->state.clear.dirty & GGL_DEPTH_BUFFER_BIT) {
  113. c->state.clear.dirty &= ~GGL_DEPTH_BUFFER_BIT;
  114. uint32_t depth = fixedToZ(c->state.clear.depth);
  115. c->state.clear.depthPacked = (depth<<16)|depth;
  116. }
  117. const uint32_t packed = c->state.clear.depthPacked;
  118. memset2d(c, c->state.buffers.depth, packed, l, t, w, h);
  119. }
  120. // XXX: do stencil buffer
  121. }
  122. static void ggl_clearColorx(void* con,
  123. GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a)
  124. {
  125. GGL_CONTEXT(c, con);
  126. c->state.clear.r = gglClampx(r);
  127. c->state.clear.g = gglClampx(g);
  128. c->state.clear.b = gglClampx(b);
  129. c->state.clear.a = gglClampx(a);
  130. c->state.clear.dirty |= GGL_COLOR_BUFFER_BIT;
  131. }
  132. static void ggl_clearDepthx(void* con, GGLclampx depth)
  133. {
  134. GGL_CONTEXT(c, con);
  135. c->state.clear.depth = gglClampx(depth);
  136. c->state.clear.dirty |= GGL_DEPTH_BUFFER_BIT;
  137. }
  138. static void ggl_clearStencil(void* con, GGLint s)
  139. {
  140. GGL_CONTEXT(c, con);
  141. c->state.clear.stencil = s;
  142. c->state.clear.dirty |= GGL_STENCIL_BUFFER_BIT;
  143. }
  144. }; // namespace android