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