1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/clear.cpp
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/memory.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "clear.h"
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "buffer.h"
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clear(void* c, GGLbitfield mask);
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearColorx(void* c,
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a);
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearDepthx(void* c, GGLclampx depth);
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearStencil(void* c, GGLint s);
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_init_clear(context_t* c)
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLContext& procs = *(GGLContext*)c;
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, clear);
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, clearColorx);
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, clearDepthx);
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, clearStencil);
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.dirty =  GGL_STENCIL_BUFFER_BIT |
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            GGL_COLOR_BUFFER_BIT |
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            GGL_DEPTH_BUFFER_BIT;
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.depth = FIXED_ONE;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void memset2d(context_t* c, const surface_t& s, uint32_t packed,
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t l, uint32_t t, uint32_t w, uint32_t h)
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint32_t size = c->formats[s.format].size;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int32_t stride = s.stride * size;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t* dst = (uint8_t*)s.data + (l + t*s.stride)*size;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    w *= size;
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ggl_likely(int32_t(w) == stride)) {
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // clear the whole thing in one call
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        w *= h;
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        h = 1;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (size) {
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 1:
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do {
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            memset(dst, packed, w);
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dst += stride;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } while(--h);
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 2:
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do {
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            android_memset16((uint16_t*)dst, packed, w);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dst += stride;
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } while(--h);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 3: // XXX: 24-bit clear.
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 4:
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do {
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            android_memset32((uint32_t*)dst, packed, w);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dst += stride;
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } while(--h);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic inline GGLfixed fixedToZ(GGLfixed z) {
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return GGLfixed(((int64_t(z) << 16) - z) >> 16);
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clear(void* con, GGLbitfield mask)
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: rgba-dithering, rgba-masking
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: handle all formats of Z and S
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint32_t l = c->state.scissor.left;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const uint32_t t = c->state.scissor.top;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t w = c->state.scissor.right - l;
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t h = c->state.scissor.bottom - t;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!w || !h)
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // unexsiting buffers have no effect...
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c->state.buffers.color.format == 0)
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mask &= ~GGL_COLOR_BUFFER_BIT;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c->state.buffers.depth.format == 0)
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mask &= ~GGL_DEPTH_BUFFER_BIT;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c->state.buffers.stencil.format == 0)
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mask &= ~GGL_STENCIL_BUFFER_BIT;
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mask & GGL_COLOR_BUFFER_BIT) {
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c->state.clear.dirty & GGL_COLOR_BUFFER_BIT) {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c->state.clear.dirty &= ~GGL_COLOR_BUFFER_BIT;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            uint32_t colorPacked = ggl_pack_color(c,
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    c->state.buffers.color.format,
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    gglFixedToIteratedColor(c->state.clear.r),
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    gglFixedToIteratedColor(c->state.clear.g),
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    gglFixedToIteratedColor(c->state.clear.b),
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    gglFixedToIteratedColor(c->state.clear.a));
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c->state.clear.colorPacked = GGL_HOST_TO_RGBA(colorPacked);
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const uint32_t packed = c->state.clear.colorPacked;
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memset2d(c, c->state.buffers.color, packed, l, t, w, h);
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mask & GGL_DEPTH_BUFFER_BIT) {
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c->state.clear.dirty & GGL_DEPTH_BUFFER_BIT) {
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c->state.clear.dirty &= ~GGL_DEPTH_BUFFER_BIT;
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            uint32_t depth = fixedToZ(c->state.clear.depth);
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c->state.clear.depthPacked = (depth<<16)|depth;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const uint32_t packed = c->state.clear.depthPacked;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memset2d(c, c->state.buffers.depth, packed, l, t, w, h);
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // XXX: do stencil buffer
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearColorx(void* con,
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a)
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.r = gglClampx(r);
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.g = gglClampx(g);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.b = gglClampx(b);
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.a = gglClampx(a);
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.dirty |= GGL_COLOR_BUFFER_BIT;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearDepthx(void* con, GGLclampx depth)
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.depth = gglClampx(depth);
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.dirty |= GGL_DEPTH_BUFFER_BIT;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_clearStencil(void* con, GGLint s)
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.stencil = s;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.clear.dirty |= GGL_STENCIL_BUFFER_BIT;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
172