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 
ggl_init_clear(context_t * c)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 
memset2d(context_t * c,const surface_t & s,uint32_t packed,uint32_t l,uint32_t t,uint32_t w,uint32_t h)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 
fixedToZ(GGLfixed z)88 static inline GGLfixed fixedToZ(GGLfixed z) {
89     return GGLfixed(((int64_t(z) << 16) - z) >> 16);
90 }
91 
ggl_clear(void * con,GGLbitfield mask)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 
ggl_clearColorx(void * con,GGLclampx r,GGLclampx g,GGLclampx b,GGLclampx a)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 
ggl_clearDepthx(void * con,GGLclampx depth)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 
ggl_clearStencil(void * con,GGLint s)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